On PowerShell
So, I’ve been using PowerShell a whole bunch lately, mostly to write prebuild / postbuild scripts for our product. Now, for most things, a batch file works fine. However, I wanted a few features that powershell really shines at (like date comparisons without downloading extra tools), and I really wanted to see just how cool Powershell is.
For those of you that don’t know what PowerShell is, imagine working in a command line shell where each command is very tiny, and has a very consistent naming convention. In order to work with these commands, you pipe the output of one command into the next, but instead of piping text, you’re piping .NET objects. Objects which you can evaluate parameters on and do crazy things with. That’s (basically) PowerShell, and it’s freaking crazy awesome.
Now, overall, I’m very impressed with Powershell, but since I’m still learning (and it’s hard to find good tutorials on the subject) I feel like there are a lot of hoops I have to jump through just to get simple things done. The simplest powershell script I’ve written is around 3 lines: a simple date compare before calling out to a generator (avoids extra work during the build process). A good example of an excellent use of powershell over batch files, since doing date compares in DOS is neigh impossible. The most complicated, this one I’m writing now, would have been a simple 1 line batch file call to xcopy, but the powershell version is much more complicated.
The task is to copy over all .h files from a directory into an “Include” directory for deployment, ignoring the “Test” directories, and not copying empty directories. The xcopy command for this is simple:
xcopy *.h ..\Include /S /Exclude:Exclude.txt
Where Exclude.txt would contain test* (which actually excludes all files starting with test, but that… might be okay). The PowerShell script, on the other hand, requires much more work. Here’s the “simplest” I could get it:
foreach($file in Get-ChildItem -filter *.h -recurse)
{
$dest = $file.FullName.Replace($currentPath, $destPath)
$destDir = [System.IO.Path]::GetDirectoryName($dest)
if(!$destDir.ToLower().Contains("test"))
{
if(!(test-path $destDir))
{
New-Item -type directory -path $destDir | Out-Null
}
Copy-Item -path $file.FullName -destination $dest
}
}
Now, I am pretty new to PowerShell, so I may be missing places where I could make simple changes and make the whole thing more readable, but I know I can’t use copy-item directly, since it will copy over empty directories when given the –Recurse command, and I can’t use –Exclude “Test*\” (or any other variant) to Get-ChildItem for some reason. I’m sure there’s a way to make the –filter parameter accept both inclusions and exclusions, but so far I’ve yet to find the help file to do it.
Has anyone else played with PowerShell? Had any luck with it?