Thursday, October 7, 2010

Managing Proxy Settings with PowerShell

I find myself changing proxy settings often on my laptop between various environments (Home, Production and Test). Generally this is no big deal. But today, I found myself switching multiple times as I was testing ISA and realized that PowerShell can easily take care of this.

At some point, I will wrap this into a GUI but for now, here is the script.

Note: I am using Jeff Hick's Test-RegistryItem.Enjoy!
function Set-Proxy {          
[cmdletbinding()]
Param (
[Parameter(Position=0,Mandatory=$True,
HelpMessage="Enter either `"Home`", `"Production`" or `"Test`".")]
[ValidateNotNullOrEmpty()]
[ValidateSet("Home", "Production", "Test")]
[String]$Location
)

$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
$url = "http://autoconf.FatBeard.com/proxy.pac"

switch ($location)
{
"Home" {
Set-ItemProperty -Path $path -Name ProxyEnable -Value 0
if (Test-RegistryItem -Path $path -Property ProxyServer) {
Remove-ItemProperty -Path $path -Name ProxyServer
}
if (Test-RegistryItem -Path $path -Property AutoConfigURL) {
Remove-ItemProperty -Path $path -Name AutoConfigURL
}
}
"Production" {
Set-ItemProperty -Path $path -Name ProxyEnable -Value 0
Set-ItemProperty -Path $path -Name AutoConfigURL -Value $url
}
"Test" {
Set-ItemProperty -Path $path -Name ProxyEnable -Value 1
Set-ItemProperty -Path $path -Name ProxyServer -Value "TestProxy-vt01:8080"
if (Test-RegistryItem -Path $path -Property AutoConfigURL) {
Remove-ItemProperty -Path $path -Name AutoConfigURL
}
}
}
}
Enjoy!

Wednesday, September 15, 2010

PowerShell & User Certificates

I was recently asked if I could generate a report of user certificates. I recalled doing this with a .NET class a while back, here is that function:
function Get-Certificate {      
[cmdletBinding()]
param([Parameter(Position=0,
Mandatory=$True,
ValueFromPipeLine=$True)]
[String]$user)

Begin {
Add-PSSnapin `
-Name Quest.ActiveRoles.ADManagement `
-ErrorAction SilentlyContinue }

Process {
Get-QADUser -Identity $user | `
Foreach { $_.DirectoryEntry.userCertificate } | `
Foreach {[System.Security.Cryptography.X509Certificates.X509Certificate2]$_} | `
Select Issuer, Subject, NotBefore,NotAfter
}
}
However, assuming you have the most recent version of the Quest Active Directory cmdlets (1.4.0), this becomes a trivial task.
Get-QADUser -Identity FatBeard | Get-QADCertificate
IssuedBy                 IssuedTo   ValidFrom  ValidTo
-------- -------- --------- -------
OSUMC EnterpriseRoot CA Fat Beard 6/3/2010 6/3/2011
OSUMC EnterpriseRoot CA Fat Beard 11/9/2009 11/9/2010
Enjoy!

Wednesday, September 1, 2010

Where's my attribute?

I am often asked why certain Active Directory attributes do not show up when using Get-QADUser (ActiveRoles Management Shell for Active Directory). An example:
(Get-QADUser -Identity FatBeard).employeeID
One might expect this to return the employeeID for Mr. FatBeard.  It doesn't and this is a desired behavior.  In order to maximize performance, the Quest cmdlets return a default list of attributes.  To see non-default attributes you have a few options:
- Use the -IncludeAllProperties parameter.  This will store ALL the attributes in the memory cache.
- Use the -IncludedProperties parameter.  For ad-hoc reporting, when all that is needed are a few attributes, this is the recommended way.
Get-QADUser -Identity FatBeard -IncludedProperties employeeID,logonCount | Select employeeID, logoncount
- Lastly, you can modify the default attributes that are returned.
$attributes = Get-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject
$attributes += 'employeeID'
Set-QADPSSnapinSettings -DefaultOutputPropertiesForUserObject $attributes
(Get-QADUser -Identity FatBeard).employeeID #Success!

Modifying the Snapin settings is only good for the current session. If you want the settings to persist, you will need to add the modification to your profile.

Enjoy!

Monday, August 16, 2010

Project Euler and PowerShell - Problem 42

Here is a PowerShell solution to Project Euler - Problem 42.
# Download the text file and create the array            
$web = New-Object System.Net.WebClient
$url = "http://projecteuler.net/project/words.txt"
$words = $web.DownloadString($url).replace("""","").split(",")

# Generate a list of Triangular numbers
[int[]]$triNums = @()
for($r=1;$r -lt 500; $r++) {
$triNums += $r*($r+1)/2
}

# Create a hashtable for numeric lookup
$lookup = @{}
$i=1
65..90 | Foreach {$lookup.add([Char]$_,$i++)}

# Get the numeric value of a word
function Get-WordValue($word) {
$letters = $word.ToCharArray()
$sum = 0
foreach ($letter in $letters) {
$sum += $lookup[[char]$letter]
}
return $sum
}

# Count the Triangular words
$Count = 0
foreach ($word in $words) {
if($triNums -contains (Get-WordValue $word)) {
#"{0}`t{1}" -f (Get-WordValue $word), $word
$Count++
}
}
$count

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!