2016-07-19 2 views
0

Я пишу сценарий powershell, который ищет пользователей в подразделении Active Directory и позволяет мне сбрасывать пароли, выбирая совпадения из списка. Я нашел Tutorial, который использует System.DirectoryServices.DirectoryEntry и System.DirectoryServices.DirectorySearcher, и изменил его так:Powershell DirectorySearcher Null Output

$objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP:\\[REDACTED]") 

##ReadSTDIN 
$strSearch = Read-Host -Prompt "Search" 
$strCat = "(&(objectCategory=User)(Name=*" + $strSearch + "*))" 
## Search Object 
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher 
$objSearcher.SearchRoot = $objDomain 
$objSearcher.PageSize = 1000 
$objSearcher.Filter = $strCat 
$objSearcher.SearchScope = "Subtree" 
#Load Required Properties into the dynObjLink 
$objSearcher.PropertiesToLoad.Add("name") 
$objSearcher.PropertiesToLoad.Add("userPrincipalName") 
$objSearcher.PropertiesToLoad.Add("SamAccountName") 

##Magical Search Function 
$colResults = $objSearcher.FindAll() 
$colResults.PropertiesLoaded 

#for every returned userID add them to a table 
ForEach ($objResult in $colResults) 
    {$a++ 
    $objResult.count 
    $objItem = $objResult.Properties 
     $objItem.name 
     $objItem.userPrincipalName 
    $results.Add($a, $objItem.name + $objItem.userPrincipalName + $objItem.SamAccountName) 
} 

#Print Table 
$results | Format-Table -AutoSize 

Это работает достаточно хорошо, но когда он печатает данные я могу получить только «имя «ценность всего, что возвращается. Все остальное становится NULL, и я не могу понять, почему.

Name Value        
---- -----             
3 {James3 [REDACTED], $null, $null}  
2 {James2 [REDACTED], $null, $null}  
1 {James1 [REDACTED], $null, $null}   

Я пробовал разные виды аутентификации и манипулируя значения, но объект DirectorySearcher кажется, только чтобы собрать «имя» значение любой записи она возвращается, независимо от того, что я загружаю в него. Помогите?

+0

try '$ objResult.Properties ['userPrincipalName']' вместо '$ objResult.Properties.userPrincipalName' –

+0

Обратите внимание, что вызовы' $ searcher.PropertiesToLoad.Add ("x") 'вызывают вывод. Вместо этого я бы рекомендовал 'AddRange':' $ searcher.PropertiesToLoad.AddRange (@ ("x", "y", 'z "))' - нет вывода, и вы можете добавить несколько свойств с одной строкой кода. –

+0

Вы также require '$ result.Properties [" userPrincipalName "] [0]' вместо просто '$ result.Properties [" userPrincipalName "]' потому что '$ result.Properties [" x "]' возвращает 'ResultValuePropertyCollection', а не' String' , поэтому вам нужно получить свой первый элемент ('[0]'). –

ответ

0

Вот немного короче (и PowerShell v2-совместимый) способ сделать это:

#requires -version 2 
param(
    [Parameter(Mandatory=$true)] 
    [String] $SearchPattern 
) 

$searcher = [ADSISearcher] "(&(objectClass=user)(name=$SearchPattern))" 
$searcher.PageSize = 1000 
$searcher.PropertiesToLoad.AddRange(@("name","samAccountName","userPrincipalName")) 
$searchResults = $searcher.FindAll() 
if ($searchResults.Count -gt 0) { 
    foreach ($searchResult in $searchResults) { 
    $properties = $searchResult.Properties 
    $searchResult | Select-Object ` 
     @{Name = "name";    Expression = {$properties["name"][0]}}, 
     @{Name = "sAMAccountName"; Expression = {$properties["samaccountname"][0]}}, 
     @{Name = "userPrincipalName"; Expression = {$properties["userprincipalname"][0]}} 
    } 
} 
$searchResults.Dispose() 

Обратите внимание, что нет никакой необходимости, чтобы создать список и выход после этого. Просто выведите каждый результат поиска. Поместите этот код в файл сценария и назвать его:

PS C:\Scripts> .\Searcher.ps1 "*dyer*" 

Если параметр опущен, PowerShell запросит для него (потому что параметр помечен как обязательный).