为什么我确定用户是否在组中的条件总是返回 false?

问题描述

我正在编写一个脚本,需要检测正在执行的用户帐户是否是域管理员。我通过获取当前用户并检查他们是否在域管理员安全组中来做到这一点。

#Get current user
$CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | Out-String
$CurrentUser = $CurrentUser -replace 'DOMAIN\\' 

#Get list of Domain Admins members
$DomainAdmins = Get-ADGroupMember -Identity "Domain Admins" -Recursive | Select -ExpandProperty SamAccountName | Out-String

#Relevant condition
If ($DomainAdmins -like ($CurrentUser)) {
     Write-Output "You're a domain admin." #example
}
Else {
     Write-Output "You're not a domain admin."
}

使用域管理员帐户从我们的域控制器运行时,此脚本始终运行 Else 代码

我也尝试过使用 -contains.contains(),结果完全相同。我已经验证 $CurrentUser 值准确地代表了当前用户,并且 $DomainAdmins 列出了预期的用户列表。

我也可以这样做:

if ($DomainAdmins -contains ("USERNAME")) {Write-host "true"}

其中 USERNAME 是直接输入的当前用户(大小写正确与否),当该用户是组成员时,它会正确返回 true。

解决方法

试试这个:

$userSID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value

$DomainAdmins = Get-ADGroupMember -Identity "Domain Admins" -Recursive

if($DomainAdmins.SID.Contains($userSID))
{
     Write-Output "You're a domain admin."
}
...

# OR 

if($userSID -in $DomainAdmins.SID)
{
     Write-Output "You're a domain admin."
}
...

# OR

if($DomainAdmins.SID -contains $userSID)
{
    Write-Output "You're a domain admin."
}

Out-String 上的 Get-ADGroupMember 正在将您的 array 转换为 string,这就是您不能将其用作比较的原因:

PS /> @(
    'one'
    'two'
    'three'
) -contains 'one'
True

PS /> (@(
    'one'
    'two'
    'three'
) | Out-String) -contains 'one'
False

替代方法,而不是使用 Get-ADGroupMember

$userSID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value

$domainAdminsDN = (Get-ADGroup -Identity "Domain Admins").DistinguishedName
$recursiveMembers = Get-ADUser -LDAPFilter "(memberOf:1.2.840.113556.1.4.1941:=$domainAdminsDN)"

if($recursiveMembers.SID.Contains($userSID))
{
    Write-Output "You're a domain admin."
}
...
...
,

我的首选方法是检查用户的 function App({ users }) { const userQueries = useQueries( users?.map(user => { return { queryKey: ['user',user.id],queryFn: () => fetchUserById(user.id),} }) ?? [] ) } 属性。当您有多个域或其他奇怪的东西时,将它们保留为 AD 对象会更好一些:

MemberOf

您的 # check if DA $DAdn = (Get-ADGroup 'Domain Admins').distinguishedname If ( Get-ADUser -LDAPFilter "(&(SamAccountName=$Env:USERNAME)(MemberOf:1.2.840.113556.1.4.1941:=$DAdn))" ) { Write-Output "You're a domain admin." #example } 变量是包含成员的单个字符串,而不是列表对象。使用 $DomainAdmins 足以在没有 ... | Select -ExpandProperty SamAccountName 的情况下获取您的列表。

,

-contains 在集合中查找完全匹配,而不是子字符串。

您必须从 Out-String 中删除 $DomainAdmins,使其成为一个列表并确保名称完全匹配,或者使用 .Contains(...) 在 {{ 1}} 字符串