AD Tricks: How many objects do you have in your AD, part 2

Powershell needs less (less.exe)



copy cygwin1.dll and less.exe from cygwin to the system32 directory

on windows 2008 R2 I had to create a new directory put the 2 files in it and add that directory to the %PATH%


Search and install PowerShell modules easy


(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex

Get-Command -Module psget


Carriage return line feed

Seems like the transcript log wants my scripts to have a carriage return.

Start-transcript c:\temp\test.log

Write-Host "Sending Messages to blah $([DateTime]::Now) `r`n"


From Oreilly PowerShell Quick Reference

Tab Completion

Tab Completion function. Hey you can modify this that's cool

Get-Content function:\TabExpansion

Multiline string “Here-Strings”


$myHereString = @"

This text may span multiple lines, and may

contain "quotes".


Powershell version


Grep and Sed -kinda



cat somefile.txt | where { $_ -match "expression"}


cat somefile.txt | %{$_ -replace "expression","replace"}

Run Script

powershell.exe -noexit &"c:\script dir\blah.ps1"

You need the &"...." if the script path has a space. If you just type "c:\script dir\blah.ps1" it will return

c:\script dir\blah.ps1

Reset WSFTP Password

$foo =.\wapg.exe -x 8 -n 1 -E "|?&<%\/!@#$^*',`~+=_;:()[]{}."

d:\iftpsvc\iftpaddu.exe -h hostname -mod -u username -p $foo

echo $foo > \\servername\share\FTPPassword.txt

Send Email

C:\scripts\blat.exe -tf $recipientlist -f me@blah.com -s "This is the subject" -server smtp.blah.corp -body "blah" -attach $File

Get properties

get-Service | get-Member -memberType Property

Get Service Tag

Get-WmiObject win32_SystemEnclosure | Select-Object serialnumber

Accounts that have not logged on recently

No Recent Logon

Stale Computers

Stale Computers

Stale User Accounts

Stale User accounts



List all Operating System in AD

Get-QADComputer -SizeLimit 0 | Sort-Object osname -unique | Format-Table -Property osname

Get Domain Controllers


$dom = [System.DirectoryServices.ActiveDirectory.Domain]::getcurrentdomain()

#Get the DC's for the domain

$dom.DomainControllers | select Name

#Find one DC


DC's for all the domains in the forest



add-PSSnapin  quest.activeroles.admanagement

Test if it is loaded before loading the snappin

IF (Get-PSSnapin | where {$_.name -eq "quest.activeroles.admanagement"})

   {write-host "Quest Active Roles snapin already loaded"}


   {add-PSSnapin  quest.activeroles.admanagement}

 Line Count

get-content H:\Machinelist.csv | Measure-Object

get-content H:\Machinelist.csv | Measure-Object -line -word -character

$foo = get-content H:\Machinelist.csv



Querry User info

List  users not in a group

Get-QADUser -NotMemberOf "All Users"

Get-QADUser -SizeLimit 0 -ErrorAction SilentlyContinue -Enabled -NotMemberOf "All Users"

Get-QADUser -SizeLimit 0 -NotMemberOf "All Users" | Where-Object { $_.WebPage -ne "Non-User Account" -and $_.WebPage -ne "Consultants" }

Get-QADUser -SizeLimit 0 -NotMemberOf "All Users" | Where-Object { $_.WebPage -ne "Non-User Account" -and $_.WebPage -ne "Consultants" } | Select-Object -property "WebPage","SAMAccountName","DN"

Querry Office Field

Search AD for users at a specific branch

Get-QADUser -SizeLimit 0 -ErrorAction SilentlyContinue -Enabled | where { $_.Office -match "^35300" }| Format-Table Name,Office,DN

Prompt user for input

$branch = Read-Host "Branch Number " ; Get-QADUser -SizeLimit 0 -ErrorAction SilentlyContinue -Enabled | where { $_.Office -match "^$branch" }| Format-Table Name,Office,DN

Get Service Pack

get-QADComputer -computerRole 'DomainController' | format-table -property computername, osname, osversion, osservicepack

Get-QADComputer -SizeLimit 0 | Where-Object { $_.osname -eq "Windows Server 2003" -and  $_.osservicepack -ne "Service Pack 2" } | format-table -property computername, osname, osversion, osservicepack

Get-QADComputer -sizelimit 0 | Where-Object { $_.name -like "?L*" } | format-table -property name, osname, osversion, osservicepack

 Get Serial Number


get-QADComputer -computerRole 'DomainController' | foreach-object {Get-WMIObject -Class "Win32_BIOS" -Computer $_.Name | Select __SERVER, SerialNumber} | export-csv 'C:\Servers.csv'

  Prompt for machine name and get serial number

$machine = Read-Host "Machine Name " ; Get-WMIObject -Class "Win32_BIOS" -Computer $Machine | Select __SERVER, SerialNumber

 Created a function to put in profile to get serial number from a machine

#modified to pass cred and prompt if not passed

#$cred = Get-Credential

#Get-Serial computer1 $cred

function Get-Serial(

   [string] $ComputerName=$(throw '$ComputerName is required'),

   [System.Management.Automation.PSCredential] $cred =$(Get-Credential))


   $bios = Get-WMIObject -Class "Win32_BIOS" -Computer $ComputerName -Credential $cred

   $system = get-wmiobject -Class "win32_computersystem" -Computer $ComputerName -Credential $cred

   #Write-Host $ComputerName", " $system.Manufacturer", " $system.Model", " $bios.SerialNumber

   Write-Host "Machine Name:  " $ComputerName

   Write-host "Manufacturer:  " $system.Manufacturer

   write-host "Model:         " $system.Model

   Write-host "Serial Number: " $bios.SerialNumber


Get a list of group members

Get-QADGroupMember noc | Select-Object -property "SAMAccountName", "eMail"


 Update Format Output

TechNet Webcast: Amazing but True: Things You Never Dreamed You Could Do with Windows PowerShell (Level 200)


Update-FormatData -PrependPath c:\scripts\formating.ps1xml

Event Log

 Get event log

Get-EventLog -logname "Security" -ComputerName server -UserName *jdoe* -newest 10

Get-EventLog -logname "Security" -ComputerName server | where {$_.eventID -eq 539 -or $_.eventID -eq 644}

Limit to only the most recent 1000 entries runs much faster

Get-EventLog -logname "Security" -ComputerName server -newest 1000 | where {$_.eventID -eq 539 -or $_.eventID -eq 644}

#Events between a time range

Get-EventLog -LogName application -Before $(Get-Date "9/30/2015 17:55") -After $(Get-Date "9/30/2015 16:30")

#Events in the last hour

Get-EventLog -LogName application -After $(Get-Date).AddHours(-1)

#connect to remote computer(s) 

#This requires PS Remoting to be enabled and that can be done via group policy pretty easily

Get-EventLog -LogName application -After $(Get-Date).AddMinutes(-1) -ComputerName server1,server2

#Type filter for error and warning only

Get-EventLog -LogName application -After $(Get-Date).AddMinutes(-220) -EntryType Error,Warning

#Filter for source

Get-EventLog -LogName application -After $(Get-Date).AddMinutes(-220) -EntryType Error,Warning -Source CertEnroll

#Filter the event message content

Get-EventLog -LogName application -After $(Get-Date).AddMinutes(-220) -EntryType Error,Warning -Source CertEnroll -Message "*RPC server is unavailable*"

Write to event log

TechNet Webcast: Amazing but True: Things You Never Dreamed You Could Do with Windows PowerShell (Level 200)


$a = New-Object -type system.diagnostics.eventlog -argumentlist system

$a.Source = "Blah"

$a.WriteEntry("The sky is falling", "Information")

You can even tell it to write to a remote machine name.

$a = New-Object -type system.diagnostics.eventlog -argumentlist system, remotemachinename


 List Printers

Get-WmiObject win32_printer -computer PrintServer | ? { $_.type -ne 1 } |sort name | Select-Object SystemName,Name,Location,ShareName,DriverName,PortName |  export-csv -notype c:\printserver.csv

 List Printers IP addresses

get-wmiobject -class "Win32_TCPIPPrinterPort" -computername PrintServer | Select-Object -Property name,hostaddress | Export-Csv c:\PrintServer.csv                                      



Nice simple example of -passthru


-PassThru: A Brief Shortcut

You can make that first approach a bit more concise by telling Add-Member to put the object back into the pipeline:

$object = New-Object –TypeNamePSObject $object | Add-Member –MemberTypeNoteProperty –Name OSBuild –Value $os.BuildNumber –PassThru | Add-Member –MemberTypeNoteProperty –Name OSVersion –Value $os.Version –PassThru | Add-Member –MemberTypeNoteProperty –Name BIOSSerial –Value $bios.SerialNumber Write-Output $object