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


Subpages (49): View All