System error 5 when accessing a network share on Windows 2008 using a DNS alias name

When I tried to access a network share on a Windows 2008 server locally (!) today using a DNS alias I configured, I got System error 5 has occurred. Access is denied (Systemfehler 5 aufgetreten. Zugriff verweigert in German):

Accessing a network share locally on a Server 2008 fails

As you see in the screenshot, the shares are enumerated correctly when using the server’s computer name (server), but access is denied when using the alias name (fileserver). However, from a client machine running Windows 7, I was able to enumerate the shares both using server and fileserver.

I found the solution to this problem in Microsoft’s Knowledge Base: Error message when you try to access a server locally by using its FQDN or its CNAME alias after you install Windows Server 2003 Service Pack 1: „Access denied“ or „No network provider accepted the given network path“:

Add the FQDN (!) of the server’s alias (e.g. fileserver.domain.local) to the value of the registry key BackConnectionHostNames under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0.

In my case, the share was accessible instantly (without restarting the server).

Migrating an existing Scuttle database to SemanticScuttle

I’ve migrated my existing bookmark collection from Scuttle to SemanticScuttle. All it took was these three lines of SQL:

  1. INSERT INTO semanticscuttle.sc_users (uId,username,password,uDatetime,uModified,name,email,homepage,uContent) (SELECT * FROM scuttle.sc_users);
  2. INSERT INTO semanticscuttle.sc_bookmarks (bId,uId,bIp,bStatus,bDatetime,bModified,bTitle,bAddress,bDescription,bHash) (SELECT * FROM scuttle.sc_bookmarks);
  3. INSERT INTO semanticscuttle.sc_bookmarks2tags (SELECT * FROM scuttle.sc_tags);

PowerShell: Configure some basic Windows settings after a fresh installation

After installing Windows I always started configuring the same old basic settings:

  • move Desktop, Documents, Music, Videos, Pictures folders to D:\
  • configure some basic settings in Windows Explorer folder options (e.g. show hidden files, show file extensions)
  • remove Internet Explorer from taskbar and add PowerShell to it

Today I set up a few virtual machines and decided to finally script the above steps with PowerShell to save some time. Here’s the final script:

  1. function changeUserFolders()
  2. {
  3.     $profileRoot = "D:\Profil\Stefan\";
  5.     $folderSettings = @{
  6.         "Desktop" = "Desktop";
  7.         "Personal" = "Dokumente";
  8.         "My Music" = "Musik";
  9.         "My Pictures" = "Bilder";
  10.         "My Video" = "Videos";
  11.         "{374DE290-123F-4565-9164-39C4925E467B}" = "D:\Download";
  12.     };
  14.     $regkeys = @("HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders", "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders");
  16.     foreach ($key in $folderSettings.keys)
  17.     {
  18.         $path = $folderSettings[$key];
  19.         if ($path -notmatch ":")
  20.         {
  21.             $path = [System.IO.Path]::Combine($profileRoot, $path);
  22.         }
  23.         if (!(test-path $path))
  24.         {
  25.             mkdir $path;
  26.         }
  27.         foreach ($regkey in $regkeys)
  28.         {
  29.             set-ItemProperty -path $regkey -name $key $path;
  30.         }
  31.     }
  33.     cd (gc env:\userprofile);
  34.     foreach ($dir in @("Desktop", "Documents", "Downloads", "Music", "Pictures", "Videos"))
  35.     {
  36.         del $dir -force -recurse;
  37.     }
  38. }
  40. function setExplorerSettings()
  41. {
  42.     $settings = @{
  43.         "Hidden" = 1;
  44.         "SuperHidden" = 1;
  45.         "HideFileExt" = 0;
  46.         "WebView" = 0;
  47.         "SeparateProcess" = 1;
  48.         "DontPrettyPath" = 1;
  49.         "SharingWizardOn" = 0;
  50.         "AlwaysShowMenus" = 1;
  51.         "HideDrivesWithNoMedia" = 0;
  52.         "NavPaneShowAllFolders" = 1;
  53.         "NavPaneExpandToCurrentFolder" = 1;
  54.     };
  56.     foreach ($key in $settings.keys)
  57.     {
  58.         Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -name $key -value $settings[$key];
  59.     }
  60.     stop-process processname explorer
  61. }
  63. function getVerbs($dir, $file)
  64. {
  65.     $shell = new-object com "Shell.Application";
  66.     $folder = $shell.Namespace($dir);
  67.     $item = $folder.Parsename($file);
  68.     return $item.Verbs();
  69. }
  71. function executeVerb($dir, $file, $verb)
  72. {
  73.     $verb = (getVerbs $dir $file) | ? {$_.Name -eq $verb};
  74.     if ($verb)
  75.     {
  76.         $verb.DoIt();
  77.     }
  78. }
  80. function pinToTaskbar($dir, $file)
  81. {
  82.     executeVerb $dir $file "An Tas&kleiste anheften";
  83. }
  85. function unpinToTaskbar($dir, $file)
  86. {
  87.     executeVerb $dir $file "Von Tas&kleiste lösen";
  88. }
  90. function createLinks()
  91. {
  92.     $winDir = gc env:\SystemRoot;
  93.     $progDir = gc "env:\ProgramFiles";
  94.     $prog86Dir = gc "env:\ProgramFiles(x86)";
  96.     $psDir = [System.IO.Path]::Combine($winDir, "system32\WindowsPowerShell\v1.0");
  97.     $ieDir = [System.IO.Path]::Combine($progDir, "Internet Explorer");
  98.     $ie86Dir = [System.IO.Path]::Combine($progDir, "Internet Explorer");
  100.     pinToTaskbar $psDir "powershell.exe";
  101.     unpinToTaskbar $ieDir "iexplore.exe";
  102.     unpinToTaskbar $ie86Dir "iexplore.exe";
  103. }
  105. changeUserFolders;
  106. setExplorerSettings;
  107. createLinks;

Oracle: SELECT top N rows skipping the first X rows

Apparently, it is not possible to use Oracle’s pseudo column rownum to select rows after a given number of rows, e.g. like

  1. SELECT * FROM tab WHERE rownum > 100;

or in MySQL

  1. SELECT * FROM tab LIMIT 100,50;

Oracle’s explanation for this (from the DB reference: ROWNUM):

The first row fetched is assigned a ROWNUM of 1 and makes the condition false. The second row to be fetched is now the first row and is also assigned a ROWNUM of 1 and makes the condition false. All rows subsequently fail to satisfy the condition, so no rows are returned.

However, to skip the first X rows in your query, you can make it a subquery like this (be sure to alias rownum!):

  2.     (SELECT field1, field2, ROWNUM rn FROM tab)
  3. WHERE rn > 100;

Git ignores .gitignore when working with PowerShell

Today, a Git problem drove me nuts: I added files to the .gitignore file to make sure Git does not track and commit them to the repository. However, Git stubbornly ignored the file and kept adding all the files in my directory to the index.

As it turned out, PowerShell was the problem. I added the files in .gitignore with a simple echo test.txt > .gitignore. I got suspicious when I saw the file’s size and remembered that PowerShell uses UTF-16 to handle Strings. When editing the file in an external editor, Git recognized the content and ignored the files.

So, the solution for me was to use an external text editor for .gitignore or explicitly change the encoding when adding an entry via PowerShell using ac -path .gitignore -Value "test.txt" -Encoding ascii

Git ignores .gitignore in PowerShell due to UTF-16 encoding

PowerShell: Check whether a Windows command or executable is available

In one of my recent PowerShell scripts I needed to find out if certain commands (in my case „svn“, „git“, „ant“ and „mvn“) were available or not. I wrote this small function that tries to call the given command and returns whether it is callable.

  1. function commandAvailable($cmd, $options)
  2. {
  3.   $error.clear();
  4.   $ErrorActionPreference = "silentlycontinue";  
  5.   & $cmd $options | out-null;
  6.   if ($error[0])
  7.   {
  8.     write-host ("Command " + $cmd + " " + $options + " is not available") -foregroundcolor "red";
  9.     return $false;
  10.   }
  11.   return $true;
  12. }
  14. write-host (commandAvailable "svn" "–version");

VBoxManage: error: VT-x features locked or unavailable in MSR. (VERR_VMX_MSR_LOCKED_OR_DISABLED)

Today I wanted to add a new 64bit virtual machine to my VirtualBox installation but when I tried to power it on I got the following error message:

root@debian /home/vms/Webserver # VBoxManage startvm Webserver --type headless
Waiting for VM "Webserver" to power on...
VBoxManage: error: VT-x features locked or unavailable in MSR. (VERR_VMX_MSR_LOCKED_OR_DISABLED)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component Console, interface IConsole, callee

The VirtualBox forum lists two prerequisites for using hardware virtualization in your VMs:

  1. a 64bit processor, which apparently I had:
    root@debian /home/vms/Webserver # lscpu
    Architecture:          x86_64
    CPU op-mode(s):        32-bit, 64-bit
  2. hardware virtualization has to be enabled in the host’s BIOS, which as it turned out I didn’t have:
    root@debian /home/vms/Webserver # modprobe msr
    root@debian /home/vms/Webserver # rdmsr 0x3a

    (here’s a German description of the command above: Virtualisierungsfunktion Intel VT aktivieren)

After enabling the hardware virtualization feature (VT-X) in the host’s BIOS and restarting it, the VM could be powered on.

Oracle error ORA-01000 (maximum open cursors exceeded) occurs when querying via ODBC with C#

A colleague of mine had this interesting problem today: OdbcDataAdapter ORA-01000. When querying an Oracle database via ODBC from C# using the following code, an Oracle error ORA-01000: maximum open cursors exceeded occured after a certain number of iterations (300 in our case):

  1. static void Main(string[] args)
  2. {
  3.     var connectionString = "DSN=MYDB;UID=user;PWD=pass";
  4.     var connection = new OdbcConnection(connectionString);
  5.     var sql = "Select 1 From DUAL";
  6.     connection.Open();
  8.     for (int i = 1; i < 500; i++)
  9.     {
  10.         using (var dataAdapter = new OdbcDataAdapter(sql, connection))
  11.         {
  12.             var dataTable = new DataTable();
  13.             dataAdapter.Fill(dataTable); // -> error ORA-01000 in iteration 300
  14.             Console.WriteLine("Iteration {0,8:d} Count = {1,4}", i, dataTable.Rows.Count);
  15.         }
  16.     }
  18.     connection.Close();
  19. }

As it turns out, the OdbcCommand object, that the OdbcDataAdapter uses internally (see field OdbcDataAdapter.SelectCommand), has to be disposed explicitly to get rid of the error. A simple dataAdapter.SelectCommand.Dispose() at the end of the using block would do the job, but there is an even cleaner way:

  1. for (int i = 1; i < 500; i++)
  2. {
  3.     using (var command = new OdbcCommand(sql, connection)) // -> makes sure command gets disposed
  4.     using (var dataAdapter = new OdbcDataAdapter(command))
  5.     {
  6.         …
  7.     }
  8. }

Connecting to an Oracle database via ODBC using only the InstantClient

Until today, I thought to be able to connect to an Oracle database from your Windows machine, you need to install the complete Oracle client including the Enterprise Manager etc. (>1GB). However, today I finally found a way to use Oracle via ODBC using only the InstantClient (ca. 50MB) on the Oracle website:

  1. First of all, download the InstantClient and the corresponding ODBC drivers for your platform from Oracle’s download site.
  2. Extract the archives into a directory of your choice, e.g. D:\Dev\Oracle\instantclient_11_2 (from now on referred to as %INSTALLDIR%).
    Connect to Oracle via ODBC using the InstantClient (directory structure)
  3. Run odbc_install.exe in %INSTALLDIR%.
    Connect to Oracle via ODBC using the InstantClient (installing the ODBC driver)
  4. Create the directory %INSTALLDIR%\network\admin and place your tnsnames.ora file in that directory.
    Connect to Oracle via ODBC using the InstantClient (adding tnsnames.ora)
  5. Set the environment variable ORACLE_HOME to %INSTALLDIR%.
    Connect to Oracle via ODBC using the InstantClient (setting ORACLE_HOME)
  6. Configure a new ODBC data source using InstantClient.
    Connect to Oracle via ODBC using the InstantClient (creating an ODBC data source)

That’s it! Now you’ll be able to connect to your Oracle database via ODBC.

PowerShell: How to read contents from text files without converting the lines into an array

Apparently, PowerShell’s get-content cmdlet automatically converts the contents of text files into an array of strings, splitting the contents at the line breaks (see Using the Get-Content Cmdlet). In many cases this is convenient:

Contents of file test.txt:

gc text.txt | % { write-host „line: “ $_ }
line: 1
line: 2
line: 3

However, if you need the file’s contents as an unchanged string (e.g. to keep line breaks the way they are when working with Unix/Linux line endings) this is not what you want. In this case, you can use the .NET method File.ReadAllText() (see File.ReadAllText Method: