Saturday, August 18, 2012

PowerShell V3 - $PSDefaultParameterValues

One of the new features of PowerShell V3 that I find very helpful is having the ability to automatically pass default parameters to cmdlets or advanced functions.

Here are a few snippets of code that shows how to manipulate them.  Simply include your default parameters in your profile and script on!

# Intitial creation (perhaps place in profile)            
$PSDefaultParameterValues=@{            
"Send-MailMessage:SMTPServer"="smtp.osumc.edu";            
"Send-MailMessage:From"="Automated.Email@osumc.edu";            
"Get-Eventlog:logname"="Security";            
}            
            
# Add another one            
$PSDefaultParameterValues.Add("Send-MailMessage:Bcc","PhatBeard@osumc.edu")                  
# opps, need to modify the email address            
$PSDefaultParameterValues["Send-MailMessage:Bcc"]="FatBeard@osumc.edu"                       
# Add another one (straight out of Get-Help) that utilizes a scriptblock
$PSDefaultParameterValues+=@{"Format-Table:AutoSize"={if ($host.Name –eq "ConsoleHost"){$true}}}            
            
# Remove one            
$PSDefaultParameterValues.Remove("Get-Eventlog:logname")            
            
# Remove all of them            
$PSDefaultParameterValues.Clear()            
            
# Temporarily disable all parameters            
$PSDefaultParameterValues.Add("Disabled", $true)            
            
# Remove the temporary disable            
$PSDefaultParameterValues.Remove("Disabled")
Enjoy!

Tuesday, August 14, 2012

Windows PowerShell for Developers by Douglas Finke; O’Reilly Media


It is not often that a technical book makes you rethink how you think. Doug Finke (a Microsoft Most Valuable Professional) has achieved just that with this concise PowerShell reference.

He starts out our journey describing PowerShell as a glue language that is as programmable as Perl, Python and Ruby and takes its cues from Unix Shells. The next few steps describe getting started, and include a brief tour. He then shifts into high gear as we learn about template engines, adding PowerShell to our GUI apps and creating graphical applications within PowerShell.

The chapter on “Writing Little Languages in PowerShell” was a welcome paradigm shift for me. Having virtually no experience with Domain Specific Languages (DSL), it was a fun ride as Doug demonstrated how to create a better XML and a creating a DSL using Graphviz. The lessons in this chapter alone were worth the price of the book.

He completes our tour with coverage of integration with COM (Component Object Model – specifically Microsoft Excel) and some of highlights of PowerShell V3 (Workflows, JSON).

This was an enjoyable invigorating read; in fact, I went through it multiple times. I appreciate the developer-centric perspective that Doug displayed throughout the text.  Whether you are a seasoned developer or a weekend hacker, if you have any interest in PowerShell, I encourage you to pick up “Windows PowerShell for Developers”.

Tuesday, August 7, 2012

PowerShell, Diskpart and Exchange (Oh my!)

Was given the opportunity to work a bit on an Exchange 2007 - 2010 migration.  I was asked if supplied a csv that contained Server and folders could the following be scripted:
  • Step 1 - Create a mount point to hold the drives (M:)
  • Step 2 - Create a series of folders on the above drive
  • Step 3 - Create a series of volumes to be used to hold the database and log files
After a bit of research, it seemed feasible using a combination of PowerShell and DiskPart.
It took me a few tries to get the hang of the necessary DiskPart commands to string together to pipe, my experience with disks has primarily been with the GUI, so I able to add a bit more to my command line toolbelt.

So once the DiskPart commands were figured out, all that needed to be done is run these on the (new)Exchange servers.  Enter Invoke-Command - you should be hearing cheering, whistling and much applause as this is darn near the most useful cmdlet in PowerShell V2.

Following is a script that could be used to create 100s of volumes.

############## Step 1 ##############            
# Create the mount point for the drives            
# We create a script block consisting of the commands we need to pipe to Diskpart            
$cmds = "`"Select Disk 2`"",            
        "`"create partition primary`"",            
        "`"assign letter=m`"",            
        "`"format fs = ntfs unit=64k quick label='Databases'`""            
$string = [string]::Join(",",$cmds)            
$sb = $ExecutionContext.InvokeCommand.NewScriptBlock("$string | DiskPart")            
            
# Iterate over the 6 Exchange Servers using Invoke-Command to run or            
# script block on each server            
1..6 | foreach {            
    Invoke-Command -ComputerName "ex10mbox-vp0$_" -ScriptBlock $sb            
}            
            
############## Step 2 ##############            
# Using a supplied CSV file, create our directories            
$folders = Import-Csv -Path C:\temp\BrentFolders.csv             
$folders | foreach {            
    $path = "\\$($_.server)\M$\$($_.folder)"            
    if(-not(Test-Path -Path $path)) {            
        New-Item -Path $path -ItemType Directory            
    }            
}            
            
############## Step 3 ##############            
# Create the 10 volumes that will be used to hold the individual database and log files.            
$disk = 3            
foreach ($folder in $folders) {            
    if($i -eq 13){$i=3}            
    $cmds = "`"select disk $disk`"",            
            "`"online disk`"",            
            "`"attributes disk clear readonly`"",            
            "`"convert mbr`"",            
            "`"create partition primary`"",            
            "`"assign mount=M:\$($folder.Folder)`"",            
            "`"format fs = ntfs unit=64k quick label=$($Folder.Folder)`""             
    $disk++            
    $string = [string]::Join(",",$cmds)            
    $sb = $ExecutionContext.InvokeCommand.NewScriptBlock("$string | DiskPart")            
    Invoke-Command -ComputerName $folder.Server -ScriptBlock $sb            
}            
This could also be utilzed for SQL Server rollouts, etc.

Enjoy!

Wednesday, August 1, 2012

"Introducing Regular Expressions" By Michael Fitzgerald; O'Reilly Media


Michael Fitzgerald achieves his goal of introducing the reader to Regular Expressions.  He clearly states his intent and his expected audience in the introduction.  In addition to the inductive approach to teaching the basics of Regular Expressions to the reader, he takes the opportunity to introduce a plethora of (free) tools.  They include but are not limited to the following:

The chapters build upon each other starting with the basics:
  • Simple Pattern Matching
  • Boundaries
  • Alternation, Groups and Backreferences
  • Character Classes
  • Matching Unicode and Other Characters
  • Quantifiers
  • Lookarounds
The lessons learned in the chapters listed above are put to use in Chapter 9, "Marking up a Document with HTML".

In addition to learning the basics of Regular Expressions, the reader gets (re)introduced to Samuel Taylor Coleridge's "The Rime of the Ancyent Marinere".  A nice change from the standard, technical examples.

This concise, book is worth the investment if you are new to Regular Expressions.