Tuesday, May 18, 2010

WPK Snippets

Here is another WPK snippet for you. This one will demonstrate how to use New-Slider and New-Ellipse. Assuming that you the PowerPack Modules installed, you should be able to cut and paste the following:
Import-Module WPK           
New-Window -Name "WPK" -Title "WPK Snippets" -Width 250 -Height 175 -Show {
New-Grid -Rows 28,100 -Columns 200* {
New-TextBox -Name txtSliderValue -Column 0 -Row 1
$fill = [System.Windows.Media.Brushes]::Blue
$stroke = [System.Windows.Media.Brushes]::Black
New-Ellipse -Name oEllipse -Column 0 -Row 2 -Height 100 -Width 100 `
-Fill $fill -Stroke $stroke
New-Slider -Name Slider -Column 0 -Row 0 -Minimum 0 -Maximum 200 `
-IsSnapToTickEnabled -On_ValueChanged {
$txtSliderValue = $window | Get-ChildControl txtSliderValue
$slider = $window | Get-ChildControl Slider
$oEllipse = $window | Get-ChildControl oEllipse
$oEllipse.width = $slider.value
}
}
}
You should see something like the following:


Moving the slider triggers the -On_ValueChanged event.
Moving it around you should see the width of the ellipse change accordingly.


Download the script.

Enjoy!

Monday, May 10, 2010

WPK Snippets

I have been experimenting with the WPK module from the PowerShell PowerPack. This module enables you to easily write user interfaces within PowerShell. Think PrimalForms but with less code and staying within one IDE. The hard part of writing the UI in WPK is knowing all the methods and properties associated with a particular object. I find searching MSDN for the members very helpful. As I use the different objects (controls), I will share my findings. Up first is the New-FolderBrowserDialog. These examples are ready to be cut and pasted into PowerShell ISE.
Import-Module WPK
New-Window -Name "WPK" -Title "WPK Snippets" -Width 400 -Height 100 -Show {
New-Grid -Rows 28,28 -Columns 75,300* {
New-TextBlock -Text "Folder Path:" -Row 1 -Column 0 -Margin 3
New-TextBox -Name txtUserName -Width 300 -Row 1 -Column 1 -Margin 3
New-Button -Content "Folder" -Name btnFolder -Row 0 -Column 1 -Margin 3 -Width 300 -On_Click {
$obj = New-FolderBrowserDialog -RootFolder "MyComputer"
$obj.ShowDialog()
$txtUserName = $Window | Get-ChildControl txtUserName
$txtUserName.Text = $obj.SelectedPath }
}
}

You should see something similar to the following:


Clicking on the button brings up the familiar "Browse For Folder" Dialog box.


Select a folder and the path is placed in the appropriate textbox.


Enjoy!

Monday, March 29, 2010

Dynamic Variable Values

Once again, my good friend from Texas asked me for a little PowerShell assistance. Being an old Cold Fusion junkie, he sent me his cryptic CF code:

Disclaimer (Blogger hates Angle Brackets)
cfset variable1="blah"
cfset var2="yada"


This statement would've then returned the value of "#blahyada#"
cfoutput #Evaluate("#variable1#")var2# cfoutput

It is basically a self-renaming variable based on the value of another variable - no idea if PowerShell can do that.


After my brief Cold Fusion viewing induced nausea subsided, I decided to help him. This is the sample I sent him:
$DallasAddress = "123 Cowboy Ave."
$ColumbusAddress = "456 Hayes St."
$ClevelandAddress = "910 Kosar Blvd."

$loc = "Dallas"
# Returns "123 Cowboy Ave."
(Get-Variable ($loc+"Address")).value


He is now happy and has learned a little bit more PowerShell. As for me, he has added yet another 6 bottles of my favorite beverage to the till.
Enjoy!

Thursday, March 11, 2010

Query DNS with PowerShell

Following is a script that will enable you to query DNS for duplicate records. Be sure to change the location of the output file!


# Using WMI, retrieve all the duplicate DNS records
$DNS = Get-WmiObject -ComputerName 'DNS-Server' `
-Namespace 'root\MicrosoftDNS' `
-Class MicrosoftDNS_AType `
-Filter "ContainerName='Your Container'" | `
Group-Object OwnerName | Where-Object {$_.Count -gt 1}

# Create our CSV file to hold the data
$file = 'c:\temp\DNS.csv'
New-Item -ItemType file -Path $file -Force
Add-Content -Path $file -Value "Name,IPAddress"

# Iterate of the DNS items grabbing the name and IPAddress
foreach ($item in $DNS) {
foreach ($IPAddresses in $item.Group) {
$value = "{0},{1}" -f $item.name,$IPAddresses.IPAddress
Add-Content -Path $file -Value $value
}
}

Results should look something like:

NameIPAddress
Server110.194.111.22
Server210.140.111.22
ServerA10.333.19.121
ServerB10.333.131.24

Enjoy!

Monday, March 1, 2010

Calling a Web Service with PowerShell

I often need to be notified of a certain condition when a scheduled script executes.
With PowerShell V2, I can take advantage of our internal paging web service by using the New-WebServiceProxy cmdlet to take care of this notification.

Check out the help on this cmdlet to see a full list of capabilities. Help New-WebServiceProxy -Full

Before we dive into the actual call, lets interrogate the web service to see what it can do.
# Create a proxy for the Paging web service
$page = New-WebServiceProxy -Uri 'http://InternalPagingService/pageservice.asmx'

#List the methods
$page Get-Member -MemberType Method
You should see something like this:

The method we are going to use is RequestSinglePage.

Enter the following to see the expected parameters:
($page Get-Member -Name RequestSinglePage).definition

Looking at the end of the definition we see 2 parameters:
- string PagerId
- string NumericOrAlphaMessage

We now have all we need to page from script!
$page.RequestSinglePage('3141','Testing Page Web Service from PowerShell')

If you need confirmation of the Web Service call, you can look at the FunctionStatus property of the executed Web Service.
($page.RequestSinglePage('3141','Test Page from PowerShell')).FunctionStatus

This returns - SUCCESS

Wrapping this web service call around some return code if fairly straight forward and is left as an exercise for the reader.

If you don't have an internal Web Service handy, try out http://www.webservicex.net/WeatherForecast.asmx

Enjoy!

Thursday, October 29, 2009

Using F# BigInt in PowerShell

Occasionally I have the need to utilize large precise numbers within PowerShell. Unfortunately, the native data types that we can use are limited in their precision.
  • Float: 7 digits
  • Double: 16 digits
  • Decimal: 29 digits

I have been researching F# and came across a data type called BigInt. I now knew that I could go back to PowerShell and take advantage of this type.

The process to do so is straight forward:
First add a reference to the FSharp.Core assembly

Add-Type -Path 'C:\Program Files (x86)\FSharp-1.9.6.16\bin\fSharp.Core.dll'

Now you do things like:
PS C:> [Microsoft.FSharp.Math.BigInt]::Pow(17,71).toString()
PS C:>2300771122759378216336589429524308
0278517973481542540644504860767306
72752491528319986033

So if you are a fan of http://projecteuler.net/ you now have another tool you can utilize.

Enjoy!

Friday, October 2, 2009

Defining Object Formatting or "How to always show Military time"

A former colleague of mine at the OSU Medical Center recently asked a PowerShell related question.

Wait - Stop - Let's start over. I must digress a moment, please be patient as I give this former colleague of mine an appropriate introduction.

This Buckeye transplant to the state of Texas is much more then a former workmate, his legacy persists in innumerable ways. I won't take your time listing many of them, but I do have to share at least one. Notice the name of my blog? It isn't named after a South Park character, nor is it named after some pirate fetish. No this transplanted Buckeye is the source of FatBeard. He has a peculiar ability to derive nicknames that persist way beyond any code or script he has ever written. I fell prey to his moniker making over 3 years ago.

OK - now that you know how FatBeard came to be, lets move on with the PowerShell related post.

Texas asked me the following:
When I type Get-ChildItem (dir, ls) and get a file listing I want to see the LastWriteTime in Military format. Easy enough! I sent him this:

Get-ChildItem | select @{Name="LWT";Expression={"{0:d} {0:HH}:{0:mm}" -f ($_.LastWriteTime)}}

His response went something like this (paraphrased for the children in the audience) . "You obtuse gluteus maximus, why would I want to type that each and every time I need a directory listing." Admittedly, he had a point.

Thus begins my first foray into extending types. Using this as my guide (http://msdn.microsoft.com/en-us/library/ms714665(VS.85).aspx), I was able to quickly accomplish the task.

My steps were as follows:

  1. Navigate to C:\Windows\System32\WindowsPowerShell\v1.0 and make a copy of FileSystem.format.ps1xml
  2. Rename the copied file (CustomFileSystem.format.ps1xml)
  3. Open the renamed file and look for the tag.
  4. You should find something like this -
    [String]::Format("{0,10} {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))
  5. As you can see, this handles the LastWriteTime formating for FileSystem related information. All we need to do is change it to meet our need. This should do -
  6. [String]::Format("{0,10} {1,2}:{2,2}:{3,2}", $_.LastWriteTime.ToString("d"),
    $_.LastWriteTime.ToString("HH"), $_.LastWriteTime.ToString("mm"),
    $_.LastWriteTime.ToString("ss"))
  7. Save the file.
  8. We now need to load the new formatting. Easy enough!
    Update-FormatData -prependPath 'C:\WINDOWS\system32\windowspowershell\v1.0\ CustomFileSystem.format.ps1xml'
  9. Verify your custom formatting by typing a few Get-ChildItem commands.
Now that wasn't to hard was it! Well Texas is happy now and you know how to modify object formatting (and how FatBeard came to be).

Enjoy!