Wednesday, September 20, 2006
Anatomy of a PowerShell script
if you do stuff, you should get PowerShell. Download it here.
I just spent a while learning some ins and outs of the scripting language, so let me try to spare you some trouble, and meanwhile talk about some of the sweet features of PowerShell scripts.
Security just a bit. Then you need to create certificates for yourself and start signing.
There's a very nice tutorial of PowerShell Right here.
I just spent a while learning some ins and outs of the scripting language, so let me try to spare you some trouble, and meanwhile talk about some of the sweet features of PowerShell scripts.
Next, if you want to run powershell scripts at all you have to relax the system
# The following starts the script and declares the parameters that it takes.
# From the command line you can query the script for its parameters,
# And this will also save you the trouble of coding in error messages when
# Args aren't provided. The familiar $argv is also there in case you want to
# handle any number of parameters.
Param([String]$server="localhost", [String]$database)
# Get-Item returns an object corresponding to a File System object.
# That in turn has all the properties that you'd hope for.
$basedir = get-item($basedirectory)
# Note that the argument to UseTheseUpgradeDirs is a call to dir, the familiar
# directory listing command. It's actually an alias for the scriptlet
# get-childitem, which returns a collection of child objects, this time
# of the "Upgrade Scripts" directory.
$upgradeDirs = UseTheseUpgradeDirs(dir "Upgrade Scripts")
# A simple loop. Note the syntax for calling static members on a class.
foreach ($dir in $upgradeDirs)
{
RunScriptsIn($dir, [DateTime]::MinValue)
}
# Here's a function declaration, with the parameter declaration below.
# push-location can also be referred to as pushd. Any scriptlet can be aliased
# Just see the user manual.
# Note the ease in filtering, where I set $files equal to the collection of
# File System objects named as such, with LastWriteTime greater than something.
function RunScriptsIn
{
Param([String]$dir, [DateTime]$modifiedAfter)
push-location($dir)
$files = dir *.sql, *.prc, *.viw, *.udf | '
where {$_.LastWriteTime -gt $modifiedAfter}
# write-host is like ECHO in batch language.
# $null is the null value. Note the strange binary operator ('=' is always
# an assignment operator here. Get used to -lt, -gt, -not, etc. Why? I don't
# know, but this script sure was easy to include in an html page.
if ($files -eq $null) {
write-host No new database changes in $dir
}
else
{
# Note the ease in shelling out to OSQL.EXE. Just like a true shell language.
foreach($file in $files)
{
write-host $file.name
$results = osql -n -S $server -U $user -P $password -d $database -i $file.name
write-host $results
}
}
# Then there's the .Net Framework support. See my earlier post for an example.
Security just a bit. Then you need to create certificates for yourself and start signing.
# This command will give you an article answering questions about signing.
# I'll give you the quick and easy though.
get-help about_signing
# The following command will tell your system to run scripts that have been
# Digitally signed so that you know who wrote them. If you feel pretty certain
# That I wrote and signed a script that you have, you can tell your system to
# Trust me as a code publisher, and subsequent scripts from me will be
# Recognized as safe.
Set-ExecutionPolicy AllSigned
# The following two commands will set up certificates for PowerShell and you.
# Don't forget to set your name under CN. You must run the makecert.exe
# That comes with .Net Framework 2.0 SDK.
makecert -n "CN=PowerShell Local Certificate Root" -a sha1 `
-eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer `
-ss Root -sr localMachine
makecert -pe -n "CN=Jane Programmer" -ss MY -a sha1 `
-eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer
# Now sign your first script, a script that will sign future scripts!
# The following is the content of the script.
# In order to sign it, create the text file, then enter PowerShell interactive
# Shell, set the $file variable yourself, and then run lines 2 and 3 in the
# shell.
param([string] $file=$(throw "Please specify a filename."))
$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
Set-AuthenticodeSignature $file $cert
There's a very nice tutorial of PowerShell Right here.