Wednesday, December 9, 2009

Windows Commands with Arguments in Powershell

I have been trying to write a simple PowerShell script that runs (invokes?) MySqlDump.exe for two days. PowerShell syntax for running commands with arguments is not obvious and I wasn't able to find it documented anywhere. While this case is specific to mysqldump, it can be applied to any command line executable with multiple arguments. The trick is to create an array of the arguments and use that as the second "argument" for the ampersand (&) call operator. Here's what my final example looked like:



[string]$pathToExe = "C:\MySQL\MySQL Server 5.1\bin\mysqldump.exe";
[string]$user = "myUser";
[string]$password = "myPass";
[string]$dbName = "myDB";
[Array]$arguments = "-u", $user, "--password=$password", $dbName;

& $pathToExe $arguments | Out-File -FileName "out.sql";




So there you have it. That's how to run an executable with spaces and arguments from PowerShell.

While this article from PowerShell.com didn't answer my questions, I thought it was pretty useful and relevent:

http://powershell.com/cs/blogs/ebook/archive/2009/03/30/chapter-12-command-discovery-and-scriptblocks.aspx

Tuesday, November 10, 2009

Changing aspnet_wp user in IIS 5.1

It's possible that no one will ever have to work with IIS 5.1 in XP again, but here you go just in case:

We needed the asp.net worker process (aspnet_wp.exe) to access a share on a remote machine. By default the "Netowrk Service" runs aspnet_wp and that user doesn't have access to remote shares. The way to change this is by changing the "processModel" attribute in your machine.config file (c:\windows\microsoft.net\framework\v2*\config\machine.config).

Mine ended up looking something like this:

<system.web>
<processmodel username="DOMAIN\username" password="password" autoconfig="true">
</processmodel>
...
</system.web>


Just make sure to restart IIS for the changes to take effect.

Tuesday, May 19, 2009

Powershell Diff Directory

I wanted to create a file diff between two different directories. Unfortunately, the Copy-Item CmdLt will not (as far as I know) create the directory structure while copying. This is a bummer. I wanted to keep all of the files in the pipe as opposed to to getting all the files first because of the number of files in the directory structure. Here's what I cam up with



$fromDir = "C:\FromDir";
$toDir = "C:\ToDir";
$diffDir = "C:\DiffDir";


Get-ChildItem -Recurse -Path $fromDir | % {
if ((Test-Path (Join-Path -Path $toDir -ChildPath ([string]$_.FullName).Replace($fromDir, ""))) -eq $false)
{
if ((Test-Path (Join-Path -Path $diffDir -ChildPath ([string]$_.Directory).Replace($fromDir, ""))) -eq $false)
{
New-Item -Type "Directory" -Path (Join-Path -Path $diffDir -ChildPath ([string]$_.Directory).Replace($fromDir, ""));
}
Copy-Item -Recurse -Force $_.FullName -Destination (Join-Path -Path $diffDir -ChildPath ([string]$_.FullName).Replace($fromDir, ""));
}
};



As always, if anyone know a better way to do this, let me know.

Wednesday, April 29, 2009

Powershell Rename-Item vs Copy-Item: Changing file names to upper case

I needed recursively change all file and sub-directory names in a directory from mixed case to upper case. To me, this felt like a problem for PowerShell, but maybe I was wrong. Here was my first attempt:



Get-ChildItem -Recurse -Path "C:\media" | % {Rename-Item $_.FullName -NewName ([string]$_.Name).ToUpper()};


However, I received the following error:


Rename-Item : Source and destination path must be different.


So it looks like PowerShell refused to rename file1 to FILE1, because it thinks that they are the same file. In order to get around this I ended up copying the entire tree, and even that command isn't particularly elegant:


Get-ChildItem -Recurse -Path "C:\media" | % {Copy-Item -Force $_.FullName ([string]$_.FullName).Replace("C:\media", "C:\MEDIA2").ToUpper()};


If there is a better way to do this, I'd love to know.

Thursday, September 18, 2008

XPlanner Authentication with NTLM

I spent most of the day setting up XPlanner and the documentation seemed to be lacking in a few spots. I'll go over the caveats I stumbled on.

The XPlanner install was happening on the lone linux box (Fedora 8) on an NT domain. The box was almost completely empty so I had to install java first. I chose to install the jsdk 1.4.2 even though that version's is EOL'd. XPlanner hasn't been updated in a while (since 2006) and I didn't want to mess w/ a new version of the sdk.

I upacked and installed the "standalone" version of XPlanner 0.7b7. So far so good. I was immediately able to use the default username/password to login.

The hardest part was figuring out how to authenticate based on our NT credentials. Most of the configuration occurs in the xplanner-0.7b7-standalone/webapps/ROOT/WEB-INF/classes/xplanner.properties file.

Here's how I was able to get the NT authentication to work. In the xplanner.properties file, find the authentication strings:


#
# XPlanner security configuration
#
xplanner.security.login[0].module=com.technoetic.xplanner.security.module.XPlannerLoginModule
xplanner.security.login[0].name=XPlanner
xplanner.security.login[0].option.userIdCaseSensitive=true
xplanner.security.login[0].option.debug=true

#xplanner.security.login[1].module=com.technoetic.xplanner.security.module.jndi.JNDILoginModule
#xplanner.security.login[1].name=JNDI
#xplanner.security.login[1].option.userIdCaseSensitive=false
#xplanner.security.login[1].option.debug=true
#xplanner.security.login[1].option.connectionURL=
#xplanner.security.login[1].option.connectionName=cn=
#xplanner.security.login[1].option.connectionPassword=
#xplanner.security.login[1].option.digest=SHA
#xplanner.security.login[1].option.userPattern=
#xplanner.security.login[1].option.userPassword=
#xplanner.security.login[1].option.authentication=simple
#xplanner.security.login[1].option.derefAliases=never
#xplanner.security.login[1].option.userSearch=cn={0}
#xplanner.security.login[1].option.userSubtree=true
#xplanner.security.login[1].option.roleBase=
#xplanner.security.login[1].option.roleName=
#xplanner.security.login[1].option.roleSearch=(uniqueMember={0})

# NTLM login module
#xplanner.security.login[2].module=com.technoetic.xplanner.security.module.ntlm.NtlmLoginModule
#xplanner.security.login[2].name=NTLM
#xplanner.security.login[2].option.userIdCaseSensitive=false
#xplanner.security.login[2].option.domain=DOMAIN
#xplanner.security.login[2].option.controller=CONTROLLER


To use the NTLM module, comment out the first set to security strings, uncomment the NTLM strings, and change the NTLM array index to 0. Here's how my file looked after I finished.


#
# XPlanner security configuration
#
#xplanner.security.login[0].module=com.technoetic.xplanner.security.module.XPlannerLoginModule
#xplanner.security.login[0].name=XPlanner
#xplanner.security.login[0].option.userIdCaseSensitive=true
#xplanner.security.login[0].option.debug=true

#xplanner.security.login[1].module=com.technoetic.xplanner.security.module.jndi.JNDILoginModule
#xplanner.security.login[1].name=JNDI
#xplanner.security.login[1].option.userIdCaseSensitive=false
#xplanner.security.login[1].option.debug=true
#xplanner.security.login[1].option.connectionURL=
#xplanner.security.login[1].option.connectionName=cn=
#xplanner.security.login[1].option.connectionPassword=
#xplanner.security.login[1].option.digest=SHA
#xplanner.security.login[1].option.userPattern=
#xplanner.security.login[1].option.userPassword=
#xplanner.security.login[1].option.authentication=simple
#xplanner.security.login[1].option.derefAliases=never
#xplanner.security.login[1].option.userSearch=cn={0}
#xplanner.security.login[1].option.userSubtree=true
#xplanner.security.login[1].option.roleBase=
#xplanner.security.login[1].option.roleName=
#xplanner.security.login[1].option.roleSearch=(uniqueMember={0})

# NTLM login module
xplanner.security.login[0].module=com.technoetic.xplanner.security.module.ntlm.NtlmLoginModule
xplanner.security.login[0].name=NTLM
xplanner.security.login[0].option.userIdCaseSensitive=false
xplanner.security.login[0].option.domain=DOMAIN
xplanner.security.login[0].option.controller=CONTROLLER


The NTLM module uses the local DB as a fall back, so any logins that you creaed locally that aren't in the Active Directory should still work.

Tuesday, September 9, 2008

JPEG Marker codes

I'm doing a bit of JPEG manipulation for a project and it took me longer than I would have liked to find a consise table of JPEG segment markers or frame markers or whatever you want to call them. Here's a C# enum with all the values. Hopefully that will save some typing for you.

        public enum JpegMarkers
        {
            // Start of Frame markers, non-differential, Huffman coding
            HuffBaselineDCT = 0xFFC0,
            HuffExtSequentialDCT = 0xFFC1,
            HuffProgressiveDCT = 0xFFC2,
            HuffLosslessSeq = 0xFFC3,

            // Start of Frame markers, differential, Huffman coding
            HuffDiffSequentialDCT = 0xFFC5,
            HuffDiffProgressiveDCT = 0xFFC6,
            HuffDiffLosslessSeq = 0xFFC7,

            // Start of Frame markers, non-differential, arithmetic coding
            ArthBaselineDCT = 0xFFC8,
            ArthExtSequentialDCT = 0xFFC9,
            ArthProgressiveDCT = 0xFFCA,
            ArthLosslessSeq = 0xFFCB,

            // Start of Frame markers, differential, arithmetic coding
            ArthDiffSequentialDCT = 0xFFCD,
            ArthDiffProgressiveDCT = 0xFFCE,
            ArthDiffLosslessSeq = 0xFFCF,

            // Huffman table spec
            HuffmanTableDef = 0xFFC4,

            // Arithmetic table spec
            ArithmeticTableDef = 0xFFCC,

            // Restart Interval termination
            RestartIntervalStart = 0xFFD0,
            RestartIntervalEnd = 0xFFD7,

            // Other markers
            StartOfImage = 0xFFD8,
            EndOfImage = 0xFFD9,
            StartOfScan = 0xFFDA,
            QuantTableDef = 0xFFDB,
            NumberOfLinesDef = 0xFFDC,
            RestartIntervalDef = 0xFFDD,
            HierarchProgressionDef = 0xFFDE,
            ExpandRefComponents = 0xFFDF,

            // App segments
            App0 = 0xFFE0,
            App1 = 0xFFE1,
            App2 = 0xFFE2,
            App3 = 0xFFE3,
            App4 = 0xFFE4,
            App5 = 0xFFE5,
            App6 = 0xFFE6,
            App7 = 0xFFE7,
            App8 = 0xFFE8,
            App9 = 0xFFE9,
            App10 = 0xFFEA,
            App11 = 0xFFEB,
            App12 = 0xFFEC,
            App13 = 0xFFED,
            App14 = 0xFFEE,
            App15 = 0xFFEF,

            // Jpeg Extensions
            JpegExt0 = 0xFFF0,
            JpegExt1 = 0xFFF1,
            JpegExt2 = 0xFFF2,
            JpegExt3 = 0xFFF3,
            JpegExt4 = 0xFFF4,
            JpegExt5 = 0xFFF5,
            JpegExt6 = 0xFFF6,
            JpegExt7 = 0xFFF7,
            JpegExt8 = 0xFFF8,
            JpegExt9 = 0xFFF9,
            JpegExtA = 0xFFFA,
            JpegExtB = 0xFFFB,
            JpegExtC = 0xFFFC,
            JpegExtD = 0xFFFD,

            // Comments
            Comment = 0xFFFE,

            // Reserved
            ArithTemp = 0xFF01,
            ReservedStart = 0xFF02,
            ReservedEnd = 0xFFBF
        };

Wednesday, August 13, 2008

Never seen this before...

So with my new job I've been tasked to write an installer for an ASP.NET website. I wanted to be able to set a few IIS properties programatically, such as Virtual Directory permissions and locations, and the .net version used by the ASP.NET interpreter. So I searched google for this string: "programmatically set asp.net version" And here's what I got:


Interesting, I ddin't know google actually cared. I entered the captcha and on I went, but I'm starting to wonder what other strings google is blocking/censuring/limiting.