Thursday, June 23, 2011

Printer exploration with PowerShell

Following are a few printing related PowerShell one-liners that I demonstrated for a few colleagues at work. -Enjoy!
# List all printer drivers on a specific server           
Get-WmiObject -Class Win32_PrinterDriver -ComputerName PrintServer `
| Sort-Object Name `
| Select-Object Name, DriverPath

# List all properties of a specifc printer driver on a server
Get-WmiObject Win32_PrinterDriver -ComputerName PrintServer -Filter "Name='Lexmark Universal XL,3,Windows x64'"

# List Printers for a specific server
Get-WmiObject Win32_Printer -ComputerName PrintServer `
| Sort-Object Name `
| Select-Object Name, DriverName, PortName, ShareName

# List a specific printer on a server
Get-WmiObject Win32_Printer -ComputerName PrintServer -Filter "Name='P-UHC6000M-IRC2550'"

# List info on print jobs
Get-WmiObject Win32_PrintJob -ComputerName PrintServer `
| Select-Object Document, Owner,
@{Label="Status";Expression={$_.JobStatus}},
@{Label="PageCount";Expression={$_.TotalPages}},
@{Label="DateSubmitted";Expression={[System.Management.ManagementDateTimeconverter]::ToDateTime($_.TimeSubmitted)}}

# List current number of jobs in each print queue
Get-WmiObject -Class Win32_PerfFormattedData_Spooler_PrintQueue -Computer PrintServer -Filter "Name <> '_Total' and Jobs > 0" `
| Sort Jobs -Descending `
| Select name, jobs `
| Format-Table -AutoSize

Saturday, February 5, 2011

PowerShell doesn't cure insomnia

Had a bit of trouble sleeping last night, when I noticed that there was a perceptible difference in the amount of light the digital clock emanates.


It got me wondering what time displays the most light. Sure I could have manually figured it out, but isn't more exciting to write a script?

Here it is:
<#   Define a lookup table for the amount of light "bars" each number displays. #>           
$hash = @{"1"=2;"2"=5;"3"=5;"4"=4;     
"5"=5;"6"=6;"7"=3;"8"=7;
"9"=5;"0"=6;":"=0}
$max=0
for ($hour = 1; $hour -le 12; $hour++) {
for ($minute = 0;$minute -lt 60; $minute++) {
$time = "{0}:{1:0#}" -f $hour, $minute
$timeArray = $time.ToCharArray()
$sum=0
foreach ($char in $timeArray) {
$sum+= $hash[[string]$char]
}
if ($sum -gt $max) {
$max, $maxTime =$sum, $time
}
}
}
"{0}`t{1}"-f $max, $maxTime
Enjoy!

Project Euler 112

A brute force attack on Project Euler #112. I suspect there is a more efficient algorithm for this (not using string conversions), but this works.
function Test-Bouncy {          
param([int]$num)
$up=$down=$false
$numArray = $num.ToString().ToCharArray()
$length = $numArray.Length
for($i=1; $i -lt $length; $i++) {
if ($numArray[$i-1] -lt $numArray[$i]) {
$up = $true
}
elseif ($numArray[$i-1] -gt $numArray[$i]) {
$down = $true
}
if ($up -and $down) {
return $true
}
}
return $false
}

$isBouncy = $ratio = 0
$x = 1
while ($ratio -lt .99) {
if(Test-Bouncy $x) {
$isBouncy++
$ratio = $isBouncy/$x
}
$x++
}

"{0}`t{1}" -f ($x-1),$ratio
Enjoy!

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!