W jaki sposób mogę przeprowadzić wyszukiwanie w Active Directory za pomocą Windows PowerShell?
Skrypciarze odpowiadają na Wasze pytania
Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy. |
Cześć, NN! Czołem, tutaj skrypciarz Ed Wilson. Dzisiaj jest wyjątkowy dzień, ponieważ otrzymałem właśnie egzemplarze autorskie książki Windows PowerShell 2.0 Best Practices (j.ang.), której napisanie zajęło mi półtora roku życia. Myślę, że najlepsze w pisaniu książek jest to, kiedy ktoś mówi mi, że przeczytał moje dzieło i że mu ono pomogło. Dzisiaj rano na Facebooku dostałem dwie wiadomości od zadowolonych czytelników. Skoro już mowa o Facebooku — zaproście mnie do znajomych. Lubię tę formę kontaktu. Oprócz egzemplarzy autorskich poczta przysłała mi dzisiaj paczkę herbaty genmaicha (j.ang.). Tę delikatną herbatę najlepiej parzyć przez 3-5 minut. Smakuje wyśmienicie z laską cynamonu. Piękne niebo, chłodne powietrze, pyszna herbata i ciekawa książka o Windows PowerShell zapowiadają, że dzień będzie udany. Nie zapominam jednak o sprawdzeniu wiadomości na koncie scripter@microsoft.com!
Całkowicie się z Tobą zgadzam, NN. Korzystanie z klas Directory Searcher platformy .NET jest dużo łatwiejsze niż ze staromodnych obiektów ADO, czy nawet nowszych skryptów ADO.NET. Myślę, że najbardziej zalecane rozwiązanie to takie, które będzie dla Ciebie najwygodniejsze, najbardziej elastyczne i najłatwiejsze w konserwacji.
Oto przykładowy skrypt QueryAD.Ps1, który napisałem kilka lat temu, a który wysyła kwerendę do usług domenowych w AD z wykorzystaniem obiektu ADO.
QueryAD.ps1
param(
$ou,
$domain,
$query,
[switch]$help
)
function funHelp()
{
$helpText=@"
DESCRIPTION:
NAME: QueryAD.ps1
Wysyła kwerendę do Active Directory na komputerze lokalnym lub zdalnym.
PARAMETERS:
-ou jednostka OU objęta kwerendą
-domain domena objęta kwerendą
-query używana kwerenda. Kwerenda obejmuje następujące obiekty:
< User, Group, Computer, OrganizationalUnit,
printqueue, grouppolicycontainer, ipsecpolicy,
pkicertificatetemplate, sitelink, subnet, site >
-help drukuje plik pomocy
SYNTAX:
QueryAD.ps1
Generuje wiadomość o brakującym parametrze i wyświetla pomoc
QueryAD.ps1 -domain "nwtraders.com" -ou "mytestou" -query computer
Wyświetla listę obiektów typu komputer w jednostce OU mytestou domeny
nwtraders.com
QueryAD.ps1 -help
Drukuje temat pomocy skryptu
"@
$helpText
exit
} #end funHelp
Function funQueryAD()
{
$domain = $domain -replace("^","dc=") #zastąp pierwszy znak
$domain = $domain -replace("\.",",dc=") #zastąp kropkę
if(!$ou)
{
if(!$query)
{
$strQuery = "<LDAP://$domain>;;name;subtree"
}
ELSE
{
$strQuery = "<LDAP://$domain>;(objectcategory=$query);name;subtree"
}
}
ELSE
{
$ou = $ou -replace("^","ou=") #zastąp pierwszy znak
$ou = $ou -replace("\,",",ou=") #zastąp kropkę
if(!$query)
{
$strQuery = "<LDAP://$ou,$domain>;;name;subtree"
}
ELSE
{
$strQuery = "<LDAP://$ou,$domain>;(objectcategory=$query);name;subtree"
}
}
$objConnection = New-Object -comObject "ADODB.Connection"
$objCommand = New-Object -comObject "ADODB.Command"
$objConnection.Open("Provider=ADsDSOObject;")
$objCommand.ActiveConnection = $objConnection
$objCommand.CommandText = $strQuery
$objRecordSet = $objCommand.Execute()
Do
{
$objRecordSet.Fields.item("name") |Select-Object name,Value
$objRecordSet.MoveNext()
}
Until ($objRecordSet.eof)
$objConnection.Close()
} #end funQueryAD
if($help) { "wzywanie pomocy..." ; funhelp }
if(!$domain) { "brak nazwy domeny" ; funhelp }
if(!$domain -or !$ou -or !$query) { "wymagany parametr" ; funhelp }
funqueryAD
Używając obiektu Directory Searcher, można znacznie ograniczyć nakład pracy konieczny do wysłania kwerendy do Active Directory. Skrypt SearchAllComputersInDomain.ps1 został użyty w artykule z serii „Cześć, Skrypciarze” z marca 2009 r., kiedy to poświęciliśmy tydzień na omówienie przeszukiwania Active Directory.
SearchAllComputersInDomain.ps1
$Filter = "ObjectCategory=computer"
$Searcher = New-Object System.DirectoryServices.DirectorySearcher($Filter)
$Searcher.Findall() |
Foreach-Object `
-Begin { "Wyniki kwerendy $Filter: " } `
-Process { $_.properties ; "`r"} `
-End { [string]$Searcher.FindAll().Count + "Znaleziono wyniki kwerendy $Filter"
W Windows PowerShell 2.0 można nieco skrócić ten skrypt, używając akceleratora typu [adsisearcher]. Akcelerator typu [adsisearcher] eliminuje konieczność tworzenia wystąpienia klasy DirectoryServices.DirectorySearcher platformy .NET:
SearchComputersUseAdsiSearcher.ps1
$Filter = "ObjectCategory=computer"
$Searcher = [adsiSearcher]($Filter)
$Searcher.Findall() |
Foreach-Object `
-Begin { "Wyniki kwerendy $Filter: " } `
-Process { $_.properties ; "`r"} `
-End { [string]$Searcher.FindAll().Count + " Znaleziono wyniki kwerendy $Filter" }
Jeśli masz co najmniej jeden kontroler domeny Windows Server 2008 R2 oraz masz zainstalowane Narzędzia administracji zdalnej serwera dla systemu Windows 7 (RSAT), możesz użyć apletu polecenia Get-ADComputer, aby pobrać informacje o koncie komputera w usługach domenowych AD. Parametr –identity przyjmuje atrybuty samAccountName, DistinguishedName, identyfikator zabezpieczeń (SID) lub identyfikator GUID obiektu:
PS C:\> Get-ADComputer -Identity hyperv
DistinguishedName : CN=HYPERV,OU=Domain Controllers,DC=NWTraders,DC=Com
DNSHostName : HyperV.NWTraders.Com
Enabled : True
Name : HYPERV
ObjectClass : computer
ObjectGUID : 2a76b1bd-80cb-4546-a8f2-ea46d474e06a
SamAccountName : HYPERV$
SID : S-1-5-21-3746122405-834892460-3960030898-1000
UserPrincipalName :
PS C:\> Get-ADComputer -Identity 'CN=HYPERV,OU=Domain Controllers,DC=NWTraders,DC=Com'
DistinguishedName : CN=HYPERV,OU=Domain Controllers,DC=NWTraders,DC=Com
DNSHostName : HyperV.NWTraders.Com
Enabled : True
Name : HYPERV
ObjectClass : computer
ObjectGUID : 2a76b1bd-80cb-4546-a8f2-ea46d474e06a
SamAccountName : HYPERV$
SID : S-1-5-21-3746122405-834892460-3960030898-1000
UserPrincipalName :
PS C:\> Get-ADComputer -Identity S-1-5-21-3746122405-834892460-3960030898-1000
DistinguishedName : CN=HYPERV,OU=Domain Controllers,DC=NWTraders,DC=Com
DNSHostName : HyperV.NWTraders.Com
Enabled : True
Name : HYPERV
ObjectClass : computer
ObjectGUID : 2a76b1bd-80cb-4546-a8f2-ea46d474e06a
SamAccountName : HYPERV$
SID : S-1-5-21-3746122405-834892460-3960030898-1000
UserPrincipalName :
PS C:\> Get-ADComputer -Identity 2a76b1bd-80cb-4546-a8f2-ea46d474e06a
DistinguishedName : CN=HYPERV,OU=Domain Controllers,DC=NWTraders,DC=Com
DNSHostName : HyperV.NWTraders.Com
Enabled : True
Name : HYPERV
ObjectClass : computer
ObjectGUID : 2a76b1bd-80cb-4546-a8f2-ea46d474e06a
SamAccountName : HYPERV$
SID : S-1-5-21-3746122405-834892460-3960030898-1000
UserPrincipalName :
Ponieważ parametr identity jest parametrem domyślnym apletu polecenia Get-ADComputer, można go opuścić i po prostu podać nazwę komputera, którego ma dotyczyć kwerenda. Widać to poniżej:
PS C:\> Get-ADComputer win7-pc
DistinguishedName : CN=WIN7-PC,CN=Computers,DC=NWTraders,DC=Com
DNSHostName : WIN7-PC.NWTraders.Com
Enabled : True
Name : WIN7-PC
ObjectClass : computer
ObjectGUID : 3e802bb2-702a-4039-90dd-d7b624c97440
SamAccountName : WIN7-PC$
SID : S-1-5-21-3746122405-834892460-3960030898-1103
UserPrincipalName :
Dziwną cechą tego skryptu jest użycie parametru property z apletu polecenia Get-ADComputer. Można by oczekiwać, że przekazanie potokiem obiektu computer zwracanego przez aplet polecenia do apletu polecenia Format-List umożliwi pracę z właściwościami obiektu komputera. Pracując z innymi obiektami, można użyć symbolu wieloznacznego „*” i przełącznika force z apletem polecenia Format-List, aby pobrać wszystkie właściwości i wartości obiektu. Jednak, jak widać tutaj, w przypadku apletu polecenia Get-ADComputer tak nie jest:
PS C:\> Get-ADComputer win7-pc | format-list * -Force
DistinguishedName : CN=WIN7-PC,CN=Computers,DC=NWTraders,DC=Com
DNSHostName : WIN7-PC.NWTraders.Com
Enabled : True
Name : WIN7-PC
ObjectClass : computer
ObjectGUID : 3e802bb2-702a-4039-90dd-d7b624c97440
SamAccountName : WIN7-PC$
SID : S-1-5-21-3746122405-834892460-3960030898-1103
UserPrincipalName :
PropertyNames : {DistinguishedName, DNSHostName, Enabled, Name...}
PropertyCount : 9
PS C:\>
Aby uzyskać wszystkie informacje dostępne w obiekcie komputera, należy użyć parametru property z apletu polecenia Get-ADComputer, tak jak widać to poniżej:
PS C:\> Get-ADComputer -Identity win7-pc -Properties *
AccountExpirationDate :
accountExpires : 9223372036854775807
AccountLockoutTime :
AccountNotDelegated : False
AllowReversiblePasswordEncryption : False
BadLogonCount : 0
badPasswordTime : 0
badPwdCount : 0
CannotChangePassword : False
CanonicalName : NWTraders.Com/Computers/WIN7-PC
Certificates : {}
CN : WIN7-PC
codePage : 0
countryCode : 0
Created : 9/8/2009 9:48:38 PM
createTimeStamp : 9/8/2009 9:48:38 PM
Deleted :
Description :
DisplayName :
DistinguishedName : CN=WIN7-PC,CN=Computers,DC=NWTraders,DC=Com
DNSHostName : WIN7-PC.NWTraders.Com
DoesNotRequirePreAuth : False
dSCorePropagationData : {12/3/2009 6:32:30 PM, 12/3/2009 6:32:29 PM, 12/2/2009 7:18:22 AM, 12/2/2009 7:18:
22 AM...}
Enabled : True
HomedirRequired : False
HomePage :
instanceType : 4
IPv4Address : 192.168.1.110
IPv6Address :
isCriticalSystemObject : False
isDeleted :
LastBadPasswordAttempt :
LastKnownParent :
lastLogoff : 0
lastLogon : 129084954052650603
LastLogonDate : 1/15/2010 12:28:29 PM
lastLogonTimestamp : 129080501096745399
localPolicyFlags : 0
Location :
LockedOut : False
logonCount : 255
ManagedBy :
MemberOf : {}
MNSLogonAccount : False
Modified : 1/18/2010 8:41:55 AM
modifyTimeStamp : 1/18/2010 8:41:55 AM
msDS-SupportedEncryptionTypes : 28
msDS-User-Account-Control-Computed : 0
Name : WIN7-PC
nTSecurityDescriptor : System.DirectoryServices.ActiveDirectorySecurity
ObjectCategory : CN=Computer,CN=Schema,CN=Configuration,DC=NWTraders,DC=Com
ObjectClass : computer
ObjectGUID : 3e802bb2-702a-4039-90dd-d7b624c97440
objectSid : S-1-5-21-3746122405-834892460-3960030898-1103
OperatingSystem : Windows 7 Enterprise
OperatingSystemHotfix :
OperatingSystemServicePack :
OperatingSystemVersion : 6.1 (7600)
PasswordExpired : False
PasswordLastSet : 1/18/2010 8:41:55 AM
PasswordNeverExpires : False
PasswordNotRequired : False
PrimaryGroup : CN=Domain Computers,CN=Users,DC=NWTraders,DC=Com
primaryGroupID : 515
ProtectedFromAccidentalDeletion : False
pwdLastSet : 129082957152111233
SamAccountName : WIN7-PC$
sAMAccountType : 805306369
sDRightsEffective : 15
ServiceAccount : {}
servicePrincipalName : {WSMAN/win7-PC, WSMAN/win7-PC.NWTraders.Com, TERMSRV/WIN7-PC, TERMSRV/win7-PC.NWTr
aders.Com...}
ServicePrincipalNames : {WSMAN/win7-PC, WSMAN/win7-PC.NWTraders.Com, TERMSRV/WIN7-PC, TERMSRV/win7-PC.NWTr
aders.Com...}
SID : S-1-5-21-3746122405-834892460-3960030898-1103
SIDHistory : {}
TrustedForDelegation : False
TrustedToAuthForDelegation : False
UseDESKeyOnly : False
userAccountControl : 4096
userCertificate : {}
UserPrincipalName :
uSNChanged : 271739
uSNCreated : 12748
whenChanged : 1/18/2010 8:41:55 AM
whenCreated : 9/8/2009 9:48:38 PM
PS C:\>
Mam nadzieję, NN, że to ułatwi Ci przeszukiwanie Active Directory przy użyciu Windows PowerShell. Jutro przedstawimy kolejny skrypt z serii poświęconej przeszukiwaniu Active Directory.
Skrypciarze Ed Wilson i Craig Liebendorfer
Do początku strony |