PowerShell:如何转换为用户对象?

时间:2015-05-08 23:32:19

标签: powershell casting active-directory

我已经获得以下代码连接到域中的每台计算机并检查本地管理员组的成员:

$user = (User) $member;
Write-Host $user.Name
Write-Host $user.AdsPath

我想要做的是将$ member的值存储在某种$ User对象中,这样我就可以在没有所有疯狂调用者的情况下引用这些属性。

e.g。在Psudo-Code中我想要:

name : score

我是PowerShell的新手,但是......我不确定我是否真的了解如何在其中转换为对象类型。

1 个答案:

答案 0 :(得分:2)

您想要创建具有指定成员和值的自定义对象(或PSObject):

Foreach ($Computer in Get-ADComputer -Filter *){
    $Path=$Computer.Path
    $Name=([ADSI]"$Path").Name
    write-host $Name
    $members =[ADSI]"WinNT://$Name/Administrators"
    $members = @($members.psbase.Invoke("Members"))
    ForEach($member in $members){
        $propsWanted = @('Name' , 'AdsPath') # An array of the properties you want
        $properties = @{} # This is an empty hashtable, or associative array, to hold the values
        foreach($prop in $propsWanted) {
            $properties[$prop] = $member.GetType().InvokeMember($prop, 'GetProperty', $null, $member, $null)
        }
        $user = New-Object PSObject -Property $properties
        $user # This is an object representing the user
    }
}

回顾一些变化:

  1. 我将所需的所有属性名称放入数组$propsWanted中,然后迭代它以调用并获取每个属性名称。这使您可以稍后通过在单个位置添加属性名称来轻松处理更多属性。
  2. $properties哈希表将存储键/值对,其中键是属性名称,值是属性值。
  3. 填写哈希表后,您可以在创建-Property时将其传递给New-Object PSObject参数。
  4. 你应该使用你的新对象,并通过测试一些事情来看看:

    • 将其传输到Format- cmdlet以查看各种视图:

      $user | Format-Table
      $user | Format-List
      
    • 直接检查其属​​性的值:

      $user.Name
      $user.AdsPath
      
    • 如果您创建这些对象的数组,则可以过滤它们,例如:

      $user | Where-Object { $_.Name -like '*Admin' }
      

    替代

    您可以尝试使用CIM或WMI,这实际上会更友好一点:

    CIM

    $group = Get-CimInstance -ClassName Win32_Group  -Filter "Name = 'Administrators'"
    
    Get-CimAssociatedInstance -InputObject $group -ResultClassName Win32_UserAccount |
    
    select -ExpandProperty Caption
    
    Get-CimAssociatedInstance -InputObject $group -ResultClassName Win32_Group |
    
    select -ExpandProperty Caption
    

    WMI

    $query = "ASSOCIATORS OF {Win32_Group.Domain='$($env:COMPUTERNAME)',Name='Administrators'} WHERE ResultClass = Win32_UserAccount"
    
    Get-WmiObject -Query $query | Select -ExpandProperty Caption
    
    $query = "ASSOCIATORS OF {Win32_Group.Domain='$($env:COMPUTERNAME)',Name='Administrators'} WHERE ResultClass = Win32_Group"
    
    Get-WmiObject -Query $query | Select -ExpandProperty Caption
    

    .NET 3.5此方法需要:

    Add-Type -AssemblyName System.DirectoryServices.AccountManagement
    
    $ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine
    
    $context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $env:COMPUTERNAME
    
    $idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
    
    $group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, 'Administrators')
    
    $group.Members |
    
    select @{N='Domain'; E={$_.Context.Name}}, samaccountName
    

    归因

    所有上述选择都是直接来自这个"嘿,脚本专家!"文章,The Admin's First Steps: Local Group Membership。它详细介绍了所有这些,包括[ADSI]方法。值得一读。

    如何实际演员

    我刚刚意识到我并没有真正回答这个问题,即使它并不完全符合你的需要。类/类型用方括号指定。事实上,当你这样做时:

    [ADSI]"WinNT://$Name/Administrators"
    

    您将[String]"中的字符串文字)转换为[ADSI]对象,因为[ADSI]知道该如何处理它。

    其他例子:

    [int]"5"
    [System.Net.IPAddress]'8.8.8.8'
    

    因为我们不知道"用户"的类型。您正在寻找的对象(或者它甚至没有真正加载),您无法使用此方法。