【问题标题】:Powershell Array or Hash Table?Powershell 数组或哈希表?
【发布时间】:2016-06-01 07:31:35
【问题描述】:

这似乎是我缺乏的一个领域。我编写了这个脚本,如果用户不在其他 3 个组中,并且只有当他们有 Exchange GUID 时,它会将用户添加到 1 个组,但由于对 AD 的来回调用,它像往常一样慢。我已经尝试过使用哈希表的各种尝试,但我无法弄清楚如何从键中获取像 MemberOf 这样的子字符串属性。我看到了首先通过$hash = @{} 收集数据的优势,但我的各种测试总是出现空值,因为我不明白如何从中获取字符串。这是我尝试将其恢复到旧的工作版本后所拥有的……谢谢

Import-Module ActiveDirectory

    $a = Get-Date
    $Logs = "C:\scripts\SEC-E2010TierGroup3\SEC-E2010TierGroup3-additions_$((Get-Date).ToString('MM-dd-yyyy')).csv"
    $Grp0 = "SEC-E2010TierGroup0"
    $Grp1 = "SEC-E2010TierGroup1"
    $Grp2 = "SEC-E2010TierGroup2"
    $Grp3 = "SEC-E2010TierGroup3"
    #$ADUserTable = @{}

 $Users = Get-ADUser -server "dc114" -LdapFilter "(&(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))(&(objectCategory=person)(objectClass=user)(!objectClass=inetOrgPerson))(sAMAccountName=s0*)(!sAMAccountName=*-d)(!sAMAccountName=*-e)(!sAMAccountName=*-a)(!Name=Test*)(!Name=v-*)(!employeeID=\00))" -properties SamAccountName, DistinguishedName,Name, memberof, msExchMailboxGuid
    <#ForEach-Object {
        $ADUserTable[$_.SamAccountName] = $_
    }#>

    function Get-GroupMembership($DN,$group){
        $objEntry = [adsi]("LDAP://"+$DN)
        $objEntry.memberOf | where { $_ -match $group}
    }
        #Usage: 
         # Get-GroupMembership "DistinguishedName" "DomainAdmins"#>

    <#$Active = #>ForEach ($user in $Users) {

    $strName = $User.samaccountname
    $DNUser = $User.distinguishedname

    $strFilter = "(&(objectCategory=User)(samAccountName=$strName))"
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.Filter = $strFilter
    $objPath = $objSearcher.FindOne()
    $objUser = $objPath.GetDirectoryEntry()
    $Exch = $objUser.msExchMailboxGuid#>

    #If here, has an Exchange Mailbox.(Get-GroupMembership "$UserDN" "$Grp0")
    if ($Exch.count -eq 1){  

            If (Get-GroupMembership "$DNUser" "$Grp0") {(""+ $a +" [" + $User + "], User:[" + $User.value.Name + "] in SEC-E2010TierGroup0.") | Out-File -FilePath $Logs -Append
                            Continue}

                If (Get-GroupMembership "$DNUser" "$Grp1") {(""+ $a +" [" + $User + "], User:[" + $User.value.Name + "] in SEC-E2010TierGroup1.") | Out-File -FilePath $Logs -Append
                            Continue}

                    If (Get-GroupMembership "$DNUser" "$Grp2") {(""+ $a +" [" + $User + "], User:[" + $User.value.Name + "] in SEC-E2010TierGroup2.") | Out-File -FilePath $Logs -Append
                            Continue}

                        If (!(Get-GroupMembership "$DNUser" "$Grp3")) {

                        (""+ $a +" [" + $User + "], User:[" + $User.value.Name + "] not in SEC-E2010TierGroup3. Adding to group3.") | Out-File -FilePath $Logs -Append}

        }

    #If here, no Exch Mailbox.
    if ($Exch.count -eq 1) {(""+ $a +" [" + $User + "], User:[" + $User.value.Name + "] does not have Exchange GUID.") | Out-File -FilePath $Logs -Append
    continue}

    } #$Active | Export-csv C:\Scripts\SEC-E2010TierGroup3\SEC-E2010TIER-Pre-Implimentation-rpt_2-18-2016.csv -NoTypeInformation

【问题讨论】:

  • 代码中有一个智能引用。为了满足 Google Prettify,我将其替换为常规双引号。

标签: powershell hash


【解决方案1】:

我无法真正完成并重写整个内容,但我可以提供一些一般性建议。

在调用 cmdlet 时,请利用管道。通常,cmdlet 知道如何以最有效的方式处理多个项目。当每个 cmdlet 调用都有开销时,例如调用 AD cmdlet 和尤其是 Exchange cmdlet 时,这种影响会被放大。例如:

$users | ForEach-Object {
    Get-Mailbox $_
}

对比:

$users | Get-Mailbox

在第一次调用中每个用户重复连接到交换的开销,但在第二种情况下只发生一次。

因此,在可能的情况下,尽可能少地调用远程 cmdlet,构建满足未来远程 cmdlet 管道要求的集合,然后通过管道将它们输入。即使看起来需要更多的优化,它也会运行得更快。

【讨论】:

  • 好的,我试试。所以,我假设我可以说 $HasMail = $Users | Get-Mailbox 并测试 true 或 false 而不是目录搜索器方法?
  • @MarcGel 可能是的,可能添加-ErrorAction SilentlyContinue
  • 虽然是一个不错的提示,但我希望能在此处了解有关如何使用哈希表的更多信息。我可以创建一个并且可以看到其中的值,但我似乎无法像使用数组那样运行字符串比较。
  • @MarcGel 恐怕我不太明白你的问题。我没有在代码中看到您尝试创建或使用哈希表的地方,我不清楚您认为它的用途是什么。也许用一个更简洁的例子来编辑你的问题,说明你想用哈希表实现什么,什么不起作用?
猜你喜欢
  • 1970-01-01
  • 2013-07-19
  • 2017-02-18
  • 2012-04-10
  • 1970-01-01
  • 2013-06-06
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多