如何在 PowerShell 中转换为用户对象?
How can I cast as a user object in PowerShell?
我有以下代码连接到域中的每台计算机并检查本地管理员组的成员:
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){
Write-Host $member.GetType().InvokeMember("Name", 'GetProperty', $null, $member, $null)
Write-Host $member.GetType().InvokeMember("AdsPath", 'GetProperty', $null, $member, $null)
}
}
我正在尝试将 $member 的值存储在某种 $User 对象中,这样我就可以在没有所有疯狂的调用程序的情况下实际引用属性。
例如,在我想要的伪代码中:
$user = (User) $member;
Write-Host $user.Name
Write-Host $user.AdsPath
我是 PowerShell 的新手,但是...我不确定我是否真的了解如何转换为其中的对象类型。
您想要创建具有指定成员和值的自定义对象(或 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
}
}
只是回顾一些变化:
- 我将您想要的所有 属性 名称放入一个数组
$propsWanted
中,然后对其进行迭代以调用并获取每个名称。通过在一个地方添加 属性 名称,您以后可以轻松使用更多属性。
$properties
哈希表将存储一对key/value,其中键是属性名称,值是属性值。
- 哈希表填满后,可以在创建
PSObject
时将其传递给New-Object
的-Property
参数。
您应该使用您的新对象并通过测试一些东西来查看:
将其通过管道传输到 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
归因
以上所有备选方案均直接取自这篇 "Hey, Scripting Guy!" 文章,The Admin's First Steps: Local Group Membership。它详细介绍了所有这些,包括 [ADSI]
方法。值得一读。
如何实际投射
我刚刚意识到我实际上并没有回答这个问题,即使它不是您所需要的。 Classes/types 用方括号指定。事实上,当你这样做时:
[ADSI]"WinNT://$Name/Administrators"
您将 [String]
("
中的字符串文字)转换为 [ADSI]
对象,该对象有效,因为 [ADSI]
知道如何处理它。
其他示例:
[int]"5"
[System.Net.IPAddress]'8.8.8.8'
由于我们不知道您正在寻找的 "user" 对象的类型(或者它甚至没有真正加载),您不能使用此方法。
我有以下代码连接到域中的每台计算机并检查本地管理员组的成员:
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){
Write-Host $member.GetType().InvokeMember("Name", 'GetProperty', $null, $member, $null)
Write-Host $member.GetType().InvokeMember("AdsPath", 'GetProperty', $null, $member, $null)
}
}
我正在尝试将 $member 的值存储在某种 $User 对象中,这样我就可以在没有所有疯狂的调用程序的情况下实际引用属性。
例如,在我想要的伪代码中:
$user = (User) $member;
Write-Host $user.Name
Write-Host $user.AdsPath
我是 PowerShell 的新手,但是...我不确定我是否真的了解如何转换为其中的对象类型。
您想要创建具有指定成员和值的自定义对象(或 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
}
}
只是回顾一些变化:
- 我将您想要的所有 属性 名称放入一个数组
$propsWanted
中,然后对其进行迭代以调用并获取每个名称。通过在一个地方添加 属性 名称,您以后可以轻松使用更多属性。 $properties
哈希表将存储一对key/value,其中键是属性名称,值是属性值。- 哈希表填满后,可以在创建
PSObject
时将其传递给New-Object
的-Property
参数。
您应该使用您的新对象并通过测试一些东西来查看:
将其通过管道传输到
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
归因
以上所有备选方案均直接取自这篇 "Hey, Scripting Guy!" 文章,The Admin's First Steps: Local Group Membership。它详细介绍了所有这些,包括 [ADSI]
方法。值得一读。
如何实际投射
我刚刚意识到我实际上并没有回答这个问题,即使它不是您所需要的。 Classes/types 用方括号指定。事实上,当你这样做时:
[ADSI]"WinNT://$Name/Administrators"
您将 [String]
("
中的字符串文字)转换为 [ADSI]
对象,该对象有效,因为 [ADSI]
知道如何处理它。
其他示例:
[int]"5"
[System.Net.IPAddress]'8.8.8.8'
由于我们不知道您正在寻找的 "user" 对象的类型(或者它甚至没有真正加载),您不能使用此方法。