Wednesday, October 20, 2010

Getting Database counts per Exchange Server via PowerShell

Was recently asked to generate a report of the total count of items per Exchange database per server. This one-liner (broken up for readability), takes care of it.
Get-MailboxServer | Get-MailboxStatistics | `
Sort-Object DatabaseName | `
Select DatabaseName, ItemCount | `
Group-Object -Property DatabaseName | `
Foreach {
$items = ($_.Group | Measure-Object -Property ItemCount -sum).Sum
"{0}`t{1:N0}" -f $_.Name,$items
}
This will generate something like the following:
Exchange01-DB011,372,127
Exchange01-DB021,522,356
Exchange01-DB031,406,486
Exchange01-DB041,345,962
Exchange01-DB051,330,690
Exchange01-DB061,392,853
Exchange01-DB071,318,130
..........


Enjoy!

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!