These MS AD cmdlets that Get-ADComputer and Get-ADObject are part of are installed as a feature under the category "Remote Server Administration Tools" (RSAT) from Server Manager on Windows Server 2008 R2 and can be downloaded for Windows 7. There's more information about this here and here.
All the code in this article should be compatible with PowerShell version 2, which comes by default with Server 2008 R2 and Windows 7 (but you can also upgrade to PSv3 or v4 on those operating systems if you want).See this article for getting usernames.
PS C:\prog\PowerShell> Import-Module ActiveDirectory PS C:\prog\PowerShell>
Also, don't forget to look at '''Get-Help Get-ADComputer -Full'''! Here is a web version of that help.
To just dump every single computer in a domain, and possibly redirect to a file by adding " | Set-Content -enc utf8 -Path computers.txt", or just " > computers.txt". you can do it like this:PS C:\prog\PowerShell> Get-ADComputer -Filter 'ObjectClass -eq "Computer"' | Select -Expand DNSHostName 2008R2ESXI2.svendsen.local 2008r2esxi.svendsen.local srv2003r2esxi.svendsen.local siemens.svendsen.local WIN7ESXI.svendsen.local winxpesxi.svendsen.local win2k.svendsen.local vista64esxi.svendsen.local server2003.svendsen.local xptanket.svendsen.local SERVER2008.svendsen.local esxi.svendsen.local winxpssd.svendsen.local
Technically, that filter is (bloody well should be) redundant. You can also use -like instead of -eq. I'm having some trouble with wildcards in combination with text, though (such as in 'ObjectClass -like "*ompute*"'). Turns out the syntax with wildcards is quirky like that.
If you don't use Select-Object and pipe to Export-Csv, you will get a CSV file with the default values that are retrieved ("... | Export-Csv -NoTypeInformation -Encoding UTF8 -Path somefile.csv").You can also redirect to a file, and specify encoding, by piping to Set-Content rather than using the redirection operator ">", which does the same thing as Out-File (Out-File allows you to specify -Encoding). When working with text/strings, they will work equivalently, and since we're using Select-Object with the parameter -ExpandProperty ("-Exp" in the examples), we get strings. There's a lot more to be said about this, but it does not belong in this article.
Above I selected the property "DNSHostName". If you use the property "Name" instead, you will get just the host name:
PS C:\prog\PowerShell> Get-ADComputer -Filter * | Select -Expand Name 2008R2ESXI2 2008R2ESXI SRV2003R2ESXI SIEMENS WIN7ESXI WINXPESXI WIN2K VISTA64ESXI SERVER2003 XPTANKET SERVER2008 esxi WINXPSSD
I also used a different filter here. Basically, when you use the Get-ADComputer cmdlet, there should be built-in filtering that targets computer objects, so you can use any property and a wildcard match with "-like '*'" or similar. I experimented with just a wildcard ("*") to target anything, and it seems to work as intended.
Here I get the DistinguishedName and LastLogonTimestamp for a specific computer. You can replace the last "Format-Table -AutoSize" part with Export-Csv in all these examples.
PS C:\> Get-ADComputer -Filter { Name -eq 'server2012' } -Propert LastLogonTimestamp | Select DistinguishedName, LastLogonTimestamp | Format-Table -AutoSize DistinguishedName LastLogonTimestamp ----------------- ------------------ CN=SERVER2012,OU=Servers,OU=Hjemme,DC=svendsen,DC=local 131063105680111740 PS C:\> $var = Get-ADComputer -Filter { Name -eq 'server2012' } PS C:\> $var.DistinguishedName CN=SERVER2012,OU=Servers,OU=Hjemme,DC=svendsen,DC=local PS C:\> $comp = Get-ADComputer server2008 PS C:\> $comp.SamAccountName SERVER2008$
To see what OU your computer is in, here's a cute, little one-liner where we use Get-ADComputer and the $env:ComputerName environment variable via its PowerShell provider (equivalent to %COMPUTERNAME% in cmd.exe/"DOS"), include all properties with the parameter "-Propert *" (you could just specify "-Propert DistinguishedName", too, and it would be included in addition to the default properties), and then enclose this expression in parentheses, causing an object to be returned, and for us to index into its "DistinguishedName" property. Remove that part and pipe the object to " | Format-List *" (or "fl *" for short) to see all properties returned.
PS C:\> (Get-ADComputer -Identity $env:COMPUTERNAME -Propert *).DistinguishedName CN=2008R2ESXI2,OU=Domain Controllers,DC=svendsen,DC=local
PS C:\> Get-ADComputer -Filter { OperatingSystem -Like '*Windows*Server*' } -Properties OperatingSystem | >> Select Name, OperatingSystem | Format-Table -AutoSize >> Name OperatingSystem ---- --------------- 2008R2ESXI2 Windows Server 2008 R2 Standard 2008R2ESXI Windows Server 2008 R2 Standard SRV2003R2ESXI Windows Server 2003 SERVER2003 Windows Server 2003 SERVER2008 Windows Serverr 2008 Standard SERVER2012RC Windows Server 2012 Release Candidate Datacenter PS C:\>
As we can see, this works for Server 2003 through Server 2012 versions of Windows Server operating systems.
To do the opposite, and only get client operating systems, you can use -NotLike instead of -Like. If you're in an environment with AD-joined Linux computers, NAS, etc., you will also see these here.PS C:\> Get-ADComputer -Filter { OperatingSystem -NotLike '*Windows*Server*' } -Properties OperatingSystem | >> Select Name, OperatingSystem | Format-Table -AutoSize >> Name OperatingSystem ---- --------------- SIEMENS Windows XP Professional WIN7ESXI Windows 7 Professional WINXPESXI Windows XP Professional WIN2K Windows 2000 Professional VISTA64ESXI Windows VistaT Ultimate XPTANKET Windows XP Professional esxi unknown WINXPSSD Windows XP Professional VMWAREWIN7 Windows 7 Professional SS-WIN7 Windows 7 Professional WIN8VM Windows 8 Pro PS C:\>
PS C:\> Get-ADComputer -Filter 'name -eq "2008r2esxi"' -Properties OperatingSystemServicePack | select Name, OperatingSystemServicePack | ft -AutoSize Name OperatingSystemServicePack ---- -------------------------- 2008R2ESXI Service Pack 1
PS C:\> Get-ADComputer -SearchBase 'OU=Clients,OU=Hjemme,dc=svendsen,dc=local' -Filter '*' | Select -Exp Name XPTANKET WINXPSSD SIEMENS WIN7ESXI WINXPESXI WIN2K VISTA64ESXI
This OU:
PS C:\prog\PowerShell> Get-ADComputer -LDAPFilter '(objectClass=Computer)' | Select -Expand Name 2008R2ESXI2 2008R2ESXI SRV2003R2ESXI SIEMENS WIN7ESXI WINXPESXI WIN2K VISTA64ESXI SERVER2003 XPTANKET SERVER2008 esxi WINXPSSD
PS C:\prog\PowerShell> Get-ADObject -LDAPFilter '(objectClass=Computer)' | Select -Expand Name 2008R2ESXI2 2008R2ESXI SRV2003R2ESXI SIEMENS WIN7ESXI WINXPESXI WIN2K VISTA64ESXI SERVER2003 XPTANKET SERVER2008 esxi WINXPSSD
PS C:\prog\PowerShell> Get-ADComputer -Filter 'SamAccountName -like "2008*"' | Select -Exp Name 2008R2ESXI 2008R2ESXI2
And here I filter on computer names that contain "2008":
PS C:\prog\PowerShell> Get-ADComputer -Filter 'SamAccountName -like "*2008*"' | Select -Exp Name 2008R2ESXI2 2008R2ESXI SERVER2008
Of course you can also filter in the pipeline using PowerShell's Where-Object/Where, but it will be less efficient, which matters with expensive queries:
PS C:\prog\PowerShell> Get-ADComputer -Filter * | Where { $_.Name -imatch '2008' } | Select -Exp Name 2008R2ESXI2 2008R2ESXI SERVER2008
The LastLogonTimestamp you get from Get-ADComputer is apparently a "FileTime" type date. You can use [datetime]::FromFileTime() to convert it to a regular DateTime class object, and then perform calculations/comparisons.
Note from 2021-10-13: By the way, a helpful way to think about date logic is to keep in mind that "now" is always the highest/largest/latest possible time, so when comparing dates, "now" (the epoch number) is always the greatest value possible, forever. It can make your head spin a bit, like infinity tends to do. If you want to experience the latest time ever in the history of our universe, you can simply enter the present moment. Typically by focusing/anchoring on your breathing and feeling the body from the inside, based on mindfulness teachings. I digress.Here's an example for getting active/enabled computer objects that have been active in the last 90 days (+/- 9-14 days, unless you changed the LastLogonTimestamp sync interval in AD - some set it to sync every day).
(Get-ADComputer -Filter * -Properties LastLogonTimestamp -SearchBase 'OU=Servers,dc=ad,dc=example,dc=com' | Where-Object { $_.Enabled -and [datetime]::FromFileTime($_.LastLogonTimestamp) -gt ` [datetime]::Now.AddDays(-90) }).Count 3748
There I check that it's Enabled (the same as -eq $true) and then that the last logon was after 90 days ago.
To do the opposite and get inactive/disabled computer objects, change to see if the "Enabled" boolean (true or false) value is $false OR that the last logon was more than 90 days ago. Of course you can change the number from 90 to something else. There's also .AddHours(), .AddMinutes(), etc. for more fine-grained filtering (rarely needed, I'd expect).(Get-ADComputer -Filter * -Properties LastLogonTimestamp -SearchBase 'OU=Servers,dc=ad,dc=example,dc=org' | Where { $_.Enabled -eq $false -or [datetime]::FromFileTime($_.LastLogonTimestamp) -lt ` [datetime]::Now.AddDays(-90) }).Count 233
I recommend caching the date for a performance gain in advance:
$MyMagicDate = (Get-Date).AddDays(-90)
... and then compare to that in the Where-Object filter.
To preserve the results for exporting to CSV or similar, simply assign the pipeline to a variable:$OldComputers = Get-ADComputer ......... $OldComputers.Count $OldComputers | Export-Csv ..........
Here's the output from my home lab's AD (these indeed are all the computers in the Active Directory):
PS C:\prog\PowerShell> .\Get-Computers-DS.ps1 2008R2ESXI2 2008R2ESXI SRV2003R2ESXI SIEMENS WIN7ESXI WINXPESXI WIN2K VISTA64ESXI SERVER2003 XPTANKET SERVER2008 esxi WINXPSSD
Basically with DirectoryServices.DirectorySearcher, the real magic is in the LDAP query, and you might have to inspect returned objects to see what their properties are. The LDAP query is specified via the Filter property of the directory searcher object, and in this case it is "(objectClass=Computer)".
Also be aware that the property you index is case-sensitive, and that they're all listed as lower-case when you look at the returned System.DirectoryServices.ResultPropertyCollection object.Here is a ready-made script that'll just dump every single computer from the AD of the first available domain controller, using Windows' method for detecting domain controllers:
#Set-StrictMode -Version Latest #$ErrorActionPreference = 'Stop' #$DirSearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher -ArgumentList ([adsi]'') $DirSearcher = [adsisearcher]"" $DirSearcher.Filter = '(objectClass=Computer)' # These properties are part of a DirectoryServices.ResultPropertyCollection # NB! These properties need to be all lowercase! $DirSearcher.FindAll().GetEnumerator() | ForEach-Object { $_.Properties.name }
I should also mention that there's a type accelerator in PowerShell v2 (I don't know about v1.x), which allows you to skip a few steps like this (notice the two quotes after the type accelerator):
PS C:\> $DirSearcher = [adsisearcher]"" PS C:\>
$DirSearcher = New-Object -TypeName DirectoryServices.DirectorySearcher -ArgumentList ([adsi]'LDAP://OU=Clients,OU=Hjemme,DC=svendsen,DC=local')
Here I prepended "LDAP://" to the distinguished name of the OU, enclosed it in a string and cast it to an ADSI object, which was then used to to create a System.DirectoryServices.DirectorySearcher object. This targets the OU svendsen.local/Hjemme/Clients. Using "System." first when declaring the object type is optional.
If you were to use the [adsisearcher] type accelerator, it would look like this:$DirSearcher = [adsisearcher][adsi]'LDAP://OU=Clients,OU=Hjemme,DC=svendsen,DC=local'
PS C:\> $dsq = dsquery computer -limit 0 PS C:\> $dsq[0] "SERVERDCNAME,OU=Domain Controllers,DC=ad,DC=company,DC=no"PS C:\> $SrvStrings = $dsq | where { $_ -like '*OU=Servere,OU=Boxes,dc=ad,dc=company,dc=no*' }
PS C:\> $SrvStrings[0] "CN=X2-443-OS0020,OU=Servere,OU=Boxes,DC=ad,DC=company,DC=no" # You can use "OU=" (or whatever is appropriate) rather than "\w{1,2}=" - # it's an attempt at being flexible - and to allow for commas in CNs PS C:\> $Servers = $SrvStrings | %{ if ($_ -match '^"CN=(.+?),\s*\w{1,2}=') { $matches[1] } } PS C:\> $Servers[0] X2-443-OS0020 PS C:\>
PS C:\powershell> Get-QADComputer -SearchRoot internal.domain.com/someOU/someSubOU -SizeLimit 0 | %{ $_.Name } comp1 comp2 comp3 comp4 comp5 PS C:\powershell> Get-QADComputer -SearchRoot internal.domain.com/someOU/someSubOU -SizeLimit 0 | %{ $_.Name } > foo.txt PS C:\powershell> (Get-Content .\foo.txt).Count 5 PS C:\powershell> (Get-Content .\foo.txt)[1,-1] comp1 comp5
Rather than " | %{ $_.Name }", you can probably more conventionally use " | Select-Object -ExpandProperty Name". You can also use " | Out-File foo.txt" instead of " > foo.txt" - or Add/Set-Content. (Do we love or hate choices? They sort of suck when documenting.)
This script will get some data from AD and redirect it to a file. Easily adapted to other needs. This will retrieve the fields Name, OSName, OSVersion, OSServicePack and LastLogonTimeStamp. See the sample output below for what it looks like. I find sorting on LastLogonTimeStamp useful (read about it here and here). I use this script to manually inspect and just remove "old" computers if I'm going to run a command against multiple online computers, for instance.
More conventionally you will probably want to export to CSV or process objects in memory on the command line. Check Get-Help Export-Csv -Full. Basically, you'd replace the Format-Table and Out-File with something like: Get-QADComputer ... bla bla | Export-Csv -Encoding UTF8 -Delimiter ";" -NoTypeInfo computers.csvPS C:\powershell> .\get-all-ad-computers.ps1 cmdlet get-all-ad-computers.ps1 at command pipeline position 1 Supply values for the following parameters: OutputFile: test.txt Running Get-QADComputer... Start time: 05/19/2011 23:36:14 End time: 05/19/2011 23:36:28 Output file: test.txt PS C:\powershell> notepad .\test.txt PS C:\powershell> type .\test.txt | Select-Object -first 10 Name OSName OSVersion OSServicePack lastLogonTimestamp ---- ------ --------- ------------- ------------------ comp1 Windows XP Professional 5.1 (2600) Service Pack 2 17.03.2010 03:07:14 comp2 Windows XP Professional 5.1 (2600) Service Pack 2 18.03.2010 08:04:52 comp3 Windows XP Professional 5.1 (2600) Service Pack 3 18.03.2010 12:27:59 comp4 Windows XP Professional 5.1 (2600) Service Pack 3 18.03.2010 12:35:31 comp5 Windows XP Professional 5.1 (2600) Service Pack 3 18.03.2010 14:07:31 comp6 Windows XP Professional 5.1 (2600) Service Pack 3 19.03.2010 11:46:23 comp7 Windows XP Professional 5.1 (2600) Service Pack 3 20.03.2010 19:50:29
I figure you might want to get just the computer names from that output, and of course you can just run a query where you pipe Get-QADComputer to Select-Object -ExpandProperty Name, but I'll throw in a little example of getting the first "word" (non-whitespace characters in sequence) on a line. In this case you will have to remove the headers manually with notepad or another editor (or Get-Content and Select-Object -First/-Last/-Skip if you like).
Read more about the PowerShell split operator here. (note 2021-10-13: That article is actually pretty darn informational)
PS E:\temp> (gc .\computers.txt)[0,-1] comp1 Windows XP Professional 5.1 (2600) Service Pack 2 17.03.2010 03:07:14 comp7 Windows XP Professional 5.1 (2600) Service Pack 3 20.03.2010 19:50:29 PS E:\temp> gc .\computers.txt | %{ ($_ -split '\s+')[0] } comp1 comp2 comp3 comp4 comp5 comp6 comp7
Read more about PowerShell regular expressions here.
PS E:\temp> (gc .\computers.txt)[0,-1] comp1 Windows XP Professional 5.1 (2600) Service Pack 2 17.03.2010 03:07:14 comp7 Windows XP Professional 5.1 (2600) Service Pack 3 20.03.2010 19:50:29 PS E:\temp> gc .\computers.txt | %{ if ($_ -match '^(\S+)') { $matches[1] } } comp1 comp2 comp3 comp4 comp5 comp6 comp7
param([Parameter(Mandatory=$true)][string] $OutputFile)$StartTime = Get-Date
# Check that the Quest.ActiveRoles.ADManagement snapin is available if (-not (Get-PSSnapin Quest.ActiveRoles.ADManagement -registered -ErrorAction SilentlyContinue)) { 'You need the Quest ActiveRoles AD Management Powershell snapin to use this script' "www.quest.com`n" 'Please install and register this snapin. Exiting...' exit 0 } # Add the snapin and don't display an error if it's already added. # If it's not registered, this will be handled above, so this should succeed. Add-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue'Running Get-QADComputer...'
Get-QADComputer -SizeLimit 0 -IncludedProperties LastLogonTimeStamp | Select-Object Name, OSName, OSVersion, OSServicePack, LastLogonTimeStamp | #Where-Object { ($_.OSVersion -match '^5\.1') } | # Filter on XP/2003 Sort-Object @{Expression={$_.LastLogonTimeStamp};Ascending=$true} | #Export-Csv -Encoding UTF8 -Delimiter ";" -NoTypeInfo computers.csv Format-Table -AutoSize -Property Name, OSName, OSVersion, OSServicePack, LastLogonTimeStamp | Out-File $OutputFile @" Start time: $StartTime End time: $(Get-Date) Output file: $OutputFile "@
Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.