Monday, July 26, 2010

Finding instances of BitLocker

Was responding to a forum question today about finding what workstations are running BitLocker. Following is a script that does just that:
Found this posting very helpful for the PacketPrivacy.
In this example I am specifically looking for computers running Windows 7.
$w = [wmi]''          
$w.PSBase.Scope.Options.Authentication = 'PacketPrivacy'
$w.PSBase.Scope.Options.Authentication

Get-QADComputer -OSName 'Windows 7*' | Select-Object Name | `
Foreach {
Get-WmiObject -ErrorAction SilentlyContinue `
-Namespace 'root\cimv2\Security\MicrosoftVolumeEncryption' `
-Impersonation 'impersonate' `
-Authentication $w.PSBase.Scope.Options.Authentication `
-Class win32_EncryptableVolume `
-ComputerName $_.Name | Select __Server, DriveLetter
}

Enjoy!

Friday, July 23, 2010

Get-LatticePoints

I am so close to reaching the second level in Project Euler (need 50, I am at 48). Most of the problems that I have solved have been via Python, however, I am occasionally able to use PowerShell. A few of the problems ask to find lattice points within a circle.

What is a lattice point? - Think of a lattice point as an intersection on a grid. So if you had a circle with radius 1, there would be 5 lattice points: (-1,0), (0,1), (0,-1), (1,0) and (0,0).
Following is a PowerShell function that will get the number of lattice points for a given radius:

function Get-LatticePoints ([int]$radius)       
{
$count = 0
$x = -$radius
while ($x -le $radius)
{
$y = -$radius
While ($y -le $radius)
{
if($x*$x + $y*$y -le $radius*$radius)
{
$count++
}
$y++
}
$x++
}
return $count
}

for($i=1;$i -le 100;$i+=1) {
"Index: {0}`tLatticePoints: {1}" -f $i, (Get-LatticePoints $i)
}
I forsee using this function in a couple of the Euler problems.
Enjoy!

Thursday, June 3, 2010

Query AD & ND concurrently (Yep, you heard me right)

In our environment, we have Active Directory and Novell Directory Services. While I spend 95% of my time in AD, I do occasionally get asked to grab information from NDS. Instead of falling back on older tools, I thought I would look at querying NDS via PowerShell. After looking at a few .NET classes, I recalled that one of my handouts at a Central Ohio PowerShell Users Group meeting was NetCmdlets. These cmdlets greatly extend the features of Microsoft Windows PowerShell with a broad range of network management and messaging capabilities. They also happen to include Get-LDAP. Using this cmdlet, it is fairly straightforward to query NDS. Following is and example that queries AD and NDS in one line of script (broken up for readability.
Get-QADUser -Enabled -Department *92278*  Sort-Object samaccountname   `
ForEach-Object {
Get-LDAP -Server 'Novell-Server' -Search "cn=$($_.samaccountname)"
} Select-Object -Unique @{N="FullName";E={$_.FullName[0]}}, resultDN `
Export-Csv -Path c:\temp\NDS.csv -NoTypeInformation

So here is what happens:

  1. We query for enabled users in AD that are in Department 92278.
  2. We sort these users by SAMAccountName
  3. We iterate over each user calling Get-LDAP with an NDS server and the SAMAccountName as a parameter
  4. We then select FullName and the resultDN (there is a bit of magic going on here as we need to assist PowerShell with the formatting: -Unique gets rid of blank lines (don't ask me why they are there). FullName actually returns an array (once again, not sure why), we can easily grab what we want by using by forcing the format @{N="FullName";E={$_.FullName[0]}}
  5. Lastly, we kickout the results to a CSV ready for use in Excel

The results look like this...

FullNameresultDN
Alda, Alancn=Alda01,ou=IS,ou=OSU,ou=HOSP,ou=CAMPUS,o=OSU_MC
Burghoff, Garycn=Burg02,ou=IS,ou=OSU,ou=HOSP,ou=CAMPUS,o=OSU_MC
Farr, Jamiecn=Farr01,ou=IS,ou=OSU,ou=HOSP,ou=CAMPUS,o=OSU_MC

At some point, I will look at using the System.DirectoryServices Namespace to accomplish this instead of relying on a 3rd party, but for now I can check a few immediate NDS related tasks off my list.

Enjoy!

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!