执行 [adsisearcher] 并存储在哈希表或字典集合列表中的最快方法
Quickest way to do a [adsisearcher] and store in a hashtable or dictionary collection list
我正在使用 [adsisearcher] 获取 AD 用户信息,因为它比 get-aduser 快得多。我也在尝试弄清楚如何使用 LINQ 或任何其他快速的替代方法将它添加到哈希表或字典中。对我来说,我正在努力获得最佳 performance/most 效率,因为长期目标是将数据导入联系人列表。
这是我目前拥有的,效果很好,但我很好奇是否有更快的方式来组织数据?
$Start = Get-Date
$searcher=[adsisearcher]""
$searcher.Sort.PropertyName = "sn"
$searcher.Filter = "(&(extensionAttribute2=customValue)(|(mobile=*)(telephonenumber=*)))"
$colProplist = "givenname","extensionattribute2","initials","mobile","telephonenumber","sn","displayname","company","title","mail","department","thumbnailphoto","samaccountname"
foreach ($i in $colPropList){$searcher.PropertiesToLoad.Add($i) > $NULL }
$End = Get-Date
Write-Host "User info took $($Start - $End) seconds"
Write-Host ""
#----------------------------------------------------
Write-Host "Creating User Hashtable"
$Start = Get-Date
$Users=@{}
$Users = $searcher.FindAll() | ForEach-Object{
New-Object -TypeName PSCustomObject -Property @{
'FirstName' = $_.properties.givenname -join ''
'MiddleName' = $_.properties.initials -join ''
'LastName' = $_.properties.sn -join ''
'DisplayName' = $_.properties.displayname -join ''
'SamAccountName' = $_.properties.samaccountname -join ''
'Email' = $_.properties.mail -join ''
'Mobile' = $_.properties.mobile -join ''
'TelephoneNumber' = $_.properties.telephonenumber -join ''
'Title' = $_.properties.title -join ''
'Dept' = $_.properties.department -join ''
'Company' = $_.properties.company -join ''
'Photo' = $_.properties.thumbnailphoto -join ''
'ExtensionAttribute2' = $_.properties.extensionattribute2 -join ''
} | Select-Object -Property FirstName, MiddleName, LastName, DisplayName, SamAccountName, Email, Mobile, TelephoneNumber, Title, Dept, Company, Photo, ExtensionAttribute2
}
$End = Get-Date
Write-Host "User HashTable took $($Start - $End) seconds"
Write-Host ""
我听说使用 LINQ 非常快,但我在正确使用语法方面遇到了困难,而且我似乎找不到很好的文档或如何使用它的示例。
因此,就像我的评论一样,我个人认为您的脚本没有太大的改进空间。我修改了一些小东西。您应该使用 measure-command
进行测试,看看代码是使用经典 foreach
循环还是使用 foreach-object
循环运行得更快。
我还为强类型 [string]
更改了 -join ''
,我不确定,但可能会更快。
回答你的问题,为什么 -join ''
在那里,这是因为每个 属性 都是 ResultPropertyValueCollection
类型
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False ResultPropertyValueCollection System.Collections.ReadOnlyCollectionBase
通过执行 -join ''
,您将每个 属性 的值转换为字符串:
PS /> ($z.samaccountname -join '').GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
PS /> ([string] $z.samaccountname).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
但是为什么这很重要?
好吧,基本上,如果您尝试导出数据而不将这些值转换为 string
到 Csv,例如,您最终会得到类似这个(你会看到每个值的类型):
$start = Get-Date
$end = Get-Date
$searcher = [adsisearcher]::new()
$searcher.Sort.PropertyName = "sn"
$searcher.Filter = "(&(objectcategory=person)(objectclass=user)(extensionAttribute2=*)(|(mobile=*)(telephonenumber=*)))"
$colProplist = @(
'givenname', 'extensionattribute2'
'initials', 'mobile', 'telephonenumber'
'sn', 'displayname', 'company'
'title', 'mail', 'department'
'thumbnailphoto', 'samaccountname'
)
$searcher.PropertiesToLoad.AddRange($colProplist)
Write-Host "User info took $($Start - $End) seconds"
Write-Host ""
Write-Host "Creating User Hashtable"
$users = foreach($user in $searcher.FindAll()) {
$i = $user.properties
[pscustomobject]@{
FirstName = [string] $i.givenname
MiddleName = [string] $i.initials
LastName = [string] $i.sn
DisplayName = [string] $i.displayname
SamAccountName = [string] $i.samaccountname
Email = [string] $i.mail
Mobile = [string] $i.mobile
TelephoneNumber = [string] $i.telephonenumber
Title = [string] $i.title
Dept = [string] $i.department
Company = [string] $i.company
Photo = [string] $i.thumbnailphoto
ExtensionAttribute2 = [string] $i.extensionattribute2
}
}
$End = Get-Date
Write-Host "User HashTable took $($Start - $End) seconds"
Write-Host ""
我正在使用 [adsisearcher] 获取 AD 用户信息,因为它比 get-aduser 快得多。我也在尝试弄清楚如何使用 LINQ 或任何其他快速的替代方法将它添加到哈希表或字典中。对我来说,我正在努力获得最佳 performance/most 效率,因为长期目标是将数据导入联系人列表。
这是我目前拥有的,效果很好,但我很好奇是否有更快的方式来组织数据?
$Start = Get-Date
$searcher=[adsisearcher]""
$searcher.Sort.PropertyName = "sn"
$searcher.Filter = "(&(extensionAttribute2=customValue)(|(mobile=*)(telephonenumber=*)))"
$colProplist = "givenname","extensionattribute2","initials","mobile","telephonenumber","sn","displayname","company","title","mail","department","thumbnailphoto","samaccountname"
foreach ($i in $colPropList){$searcher.PropertiesToLoad.Add($i) > $NULL }
$End = Get-Date
Write-Host "User info took $($Start - $End) seconds"
Write-Host ""
#----------------------------------------------------
Write-Host "Creating User Hashtable"
$Start = Get-Date
$Users=@{}
$Users = $searcher.FindAll() | ForEach-Object{
New-Object -TypeName PSCustomObject -Property @{
'FirstName' = $_.properties.givenname -join ''
'MiddleName' = $_.properties.initials -join ''
'LastName' = $_.properties.sn -join ''
'DisplayName' = $_.properties.displayname -join ''
'SamAccountName' = $_.properties.samaccountname -join ''
'Email' = $_.properties.mail -join ''
'Mobile' = $_.properties.mobile -join ''
'TelephoneNumber' = $_.properties.telephonenumber -join ''
'Title' = $_.properties.title -join ''
'Dept' = $_.properties.department -join ''
'Company' = $_.properties.company -join ''
'Photo' = $_.properties.thumbnailphoto -join ''
'ExtensionAttribute2' = $_.properties.extensionattribute2 -join ''
} | Select-Object -Property FirstName, MiddleName, LastName, DisplayName, SamAccountName, Email, Mobile, TelephoneNumber, Title, Dept, Company, Photo, ExtensionAttribute2
}
$End = Get-Date
Write-Host "User HashTable took $($Start - $End) seconds"
Write-Host ""
我听说使用 LINQ 非常快,但我在正确使用语法方面遇到了困难,而且我似乎找不到很好的文档或如何使用它的示例。
因此,就像我的评论一样,我个人认为您的脚本没有太大的改进空间。我修改了一些小东西。您应该使用 measure-command
进行测试,看看代码是使用经典 foreach
循环还是使用 foreach-object
循环运行得更快。
我还为强类型 [string]
更改了 -join ''
,我不确定,但可能会更快。
回答你的问题,为什么 -join ''
在那里,这是因为每个 属性 都是 ResultPropertyValueCollection
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False ResultPropertyValueCollection System.Collections.ReadOnlyCollectionBase
通过执行 -join ''
,您将每个 属性 的值转换为字符串:
PS /> ($z.samaccountname -join '').GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
PS /> ([string] $z.samaccountname).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
但是为什么这很重要?
好吧,基本上,如果您尝试导出数据而不将这些值转换为 string
到 Csv,例如,您最终会得到类似这个(你会看到每个值的类型):
$start = Get-Date
$end = Get-Date
$searcher = [adsisearcher]::new()
$searcher.Sort.PropertyName = "sn"
$searcher.Filter = "(&(objectcategory=person)(objectclass=user)(extensionAttribute2=*)(|(mobile=*)(telephonenumber=*)))"
$colProplist = @(
'givenname', 'extensionattribute2'
'initials', 'mobile', 'telephonenumber'
'sn', 'displayname', 'company'
'title', 'mail', 'department'
'thumbnailphoto', 'samaccountname'
)
$searcher.PropertiesToLoad.AddRange($colProplist)
Write-Host "User info took $($Start - $End) seconds"
Write-Host ""
Write-Host "Creating User Hashtable"
$users = foreach($user in $searcher.FindAll()) {
$i = $user.properties
[pscustomobject]@{
FirstName = [string] $i.givenname
MiddleName = [string] $i.initials
LastName = [string] $i.sn
DisplayName = [string] $i.displayname
SamAccountName = [string] $i.samaccountname
Email = [string] $i.mail
Mobile = [string] $i.mobile
TelephoneNumber = [string] $i.telephonenumber
Title = [string] $i.title
Dept = [string] $i.department
Company = [string] $i.company
Photo = [string] $i.thumbnailphoto
ExtensionAttribute2 = [string] $i.extensionattribute2
}
}
$End = Get-Date
Write-Host "User HashTable took $($Start - $End) seconds"
Write-Host ""