简体   繁体   English

Powershell阵列还是哈希表?

[英]Powershell Array or Hash Table?

This seems to be an area where I am lacking. 这似乎是我所缺少的领域。 I have written this script that would add users to 1 group if they are not in any of the other 3 and only if they have an Exchange GUID, but it is slow as usual, due to the calls back and forth to AD. 我编写了此脚本,如果用户不在其他3个组中,并且只有他们具有Exchange GUID,则它将添加到1个组中,但是由于来回调用AD,它的速度和往常一样慢。 I have tried various attempts at using hash tables, but I am not able to figure out how to get sub-string properties like MemberOf from the keys. 我已经尝试过使用哈希表的各种尝试,但是我无法弄清楚如何从键中获取像MemberOf这样的子字符串属性。 I see the advantage of gathering up the data first via $hash = @{} but my various tests always come up null because I don't understand how to get strings out of it. 我看到了先通过$hash = @{}收集数据的优点,但是我的各种测试总是以null结束,因为我不知道如何从中获取字符串。 Here's what I have after trying to put it back to the old working version... Thx 这是我尝试将其恢复为旧工作版本后所拥有的... Thx

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

I can't really go through this and rewrite the whole thing but I can give some general advice. 我不能真正地重写整个过程,但是我可以给出一些一般性建议。

When it comes to calling cmdlets take advantage of the pipeline. 谈到cmdlet时,请利用管道。 Typically a cmdlet knows how to handle multiple items in the most efficient way. 通常,cmdlet知道如何以最有效的方式处理多个项目。 When each cmdlet call has overhead, like when calling AD cmdlets and especially Exchange cmdlets, this effect will be magnified. 当每个cmdlet调用都有开销时,例如调用AD cmdlet 尤其是 Exchange cmdlet时,此效果将被放大。 For example: 例如:

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

vs: vs:

$users | Get-Mailbox

The overhead of connecting to exchange is repeated per user in the first call, but only happens once in the second scenario. 在第一个呼叫中, 每个用户都会重复进行连接以交换的开销,但是在第二种情况下,连接开销仅发生一次。

So when possible, make the fewest calls to remote cmdlets you can, build collections that satisfy the pipeline requirements to future remote cmdlets, and pipe them in. Even if it seems to require more finagling, it will run much faster. 因此,在可能的情况下,请尽可能少地调用远程cmdlet,建立满足对将来的远程cmdlet的管道要求的集合,然后通过管道将它们引入。即使似乎需要更多的操作,它也会运行得更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM