Friday, November 30, 2007

Powershell equivalent of "Right()"

In VBScript, there is the the Right() function used to return the right-most X characters of a string.

After googling, I couldn't find a clear example of doing this in Powershell. Microsoft has a page on VBscript equivalents in Powershell, but their Right() page didn't give exactly what I wanted.

My delimma:
I have a Powershell script performing a nightly commit of our production servers' code shares to an SVN repository. One of the scripts calls "svn status", which returns the status of all files in the working folder as compared to the repository:
!______D:\Path\to\some\file
Where the first 6 characters are status codes, there's 1 space, then the file path (I replaced spaces with _ above for readability). What I need for performing an "svn add" or "svn delete" is just the file path. So, I needed to somehow get all EXCEPT the first 7 characters of the output into a variable.

To do this, I ended up using the .SubString() function. This is called with two arguments: the number of characters to remove, and the number of characters to return. To remove the first 7 characters, I specify "7" and then the length of the string minus 7:
$FileName = $SvnStatusLine.SubString(7,$SvnStatusLine.Length - 7)

Conversely, if you wanted to remove the LAST 7 characters, just reverse the position of the arguments.

Update:
Thanks to a knowledgeable commenter for this slicker alternative:

/\/\o\/\/ said...

in this case you might consider using remove :

$s = "!______D:\Path\to\some\file"
$s.Remove(0,7)

D:\Path\to\some\file

Greetings /\/\o\/\/


Where were you a few days ago ;-) Thanks!

Tuesday, November 13, 2007

Using the BITS ISAPI filter on Windows 2003 64-bit with Enable32bitAppOnWin64 enabled

A problem I ran into the other day was this:

We're slowly migrating from 32-bit Windows to 64-bit Windows. To prepare, we're rolling out 2003 Standard edition, 64-bit. Since our applications are still compiled 32-bit until we migrate off .NET 1.1, we have set IIS 6 to run 32-bit application pools by running:
cscript %SystemDrive%\inetpub\AdminScripts\adsutil.vbs set w3svc/AppPools/Enable32bitAppOnWin64 1
and restarting IIS.

All seemed well. Mapping .NET 1.1 (which only runs in 32-bit mode) worked fine:
%SYSTEMROOT%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis.exe -i
However, any attempt to surf our BITS-enabled IIS site resulted in error code 500. Disabling IE's unhelpful "Friendly Error Messages" showed me the message "Module Not Found".

So, I ran filemon to see what files were in use as I tried to hit the website. What I noticed was w3wp.exe, one of the worker processes of IIS6, was trying to open "c:\windows\SysWOW64\bitssrv.dll" (the BITS ISAPI dll). To confirm my settings, the "BITS Webserver Extensions" setting in my IIS6 "Webserver Extensions" pane indeed pointed to "c:\windows\system32\bitssrv.dll". In the website properties, we have a script-mapping to direct all requests to the ISAPI dll, and it too pointed to "c:\windows\system32\bitssrv.dll"

Since we set IIS to use 32-bit application pools, Windows is "helpfully" translating calls for the system folder (oddly named "system32" on Windows 64-bit) to the 32-bit system folder, named SysWOW64 (does anyone know why they didn't just leave "system32" as the 32-bit folder and make a new one "system64"?).

You can actually see this in action by running a 32-bit file manager (like TotalCommander) and see that attempts to surf c:\windows\system32 show different results between 32-bit and 64-bit apps.

This struck me as odd because there is no bitssrv.dll in the SysWOW64 folder, only in the system32 folder (meaning there is no 32-bit BITS dll, just a 64-bit one). To be sure, I looked on the Windows Server 2003 x64 CD, SP1 CD, and SP2 CD for a 32-bit version of the BITS dll. Apparently, there is no 32-bit version of the ISAPI filter for a 64-bit OS.

I copied the bitssrv.dll from a 32-bit Windows 2003 server to this server's "C:\Windows\SysWOW64\" folder and restarted IIS. Voila, BITS functioned properly.

I assume this is all by design, but it was annoying to discover. What's even more annoying is that I'll need to manually update this file for any BITS-related security patches.