如果用户位于某个AD群组中并且连接到某个网络,我正在创建一个代码来打开网站。这是我到目前为止所得到的:
$user = $env:username
$group1 = "examplegroup1"
$group2 = "examplegroup2"
if (Test-Connection "examplenetwork" -Quiet)
{
$members1 = Get-ADGroupMember -Identity $group1 | Select -ExpandProperty
SamAccountName
$members2 = Get-ADGroupMember -Identity $group2 | Select -ExpandProperty
SamAccountName
If ($members1 -contains $user -or $members2 -contains $user) {Start-Process
"examplewebsite"}
}
如果用户位于正确的群组和网络中,它可以正常工作,打开网站,但我只是想知道是否有办法压缩代码?
必须创建2' $groups
'然后重复Get-ADGroupMember
。我玩过“ForEach'但是没有设法让它发挥作用。
关于如何浓缩这个的任何想法?最好使用ForEach cmdlet。
答案 0 :(得分:1)
虽然我的另一个答案是“不要那样做”,如果你确实需要你的代码,请缩小:
$groups = 'group1', 'group2'
if ((Test-Connection -ComputerName "examplenetwork" -Quiet) -and
($env:USERNAME -in ($groups | Get-ADGroupMember -Recursive).SamAccountName))
{
Start-Process "www.example.com"
}
你真的不需要foreach。
答案 1 :(得分:0)
If (("examplegroup1", "examplegroup2" | % {Get-ADGroupMember -Identity $_} | Select -ExpandProperty SamAccountName) -Contains $env:username) {Start-Process "examplewebsite"}
答案 2 :(得分:0)
我可能会向后做:
$user = $env:username
$groups = "examplegroup1", "examplegroup1"
$CheckMembership = Get-ADUser -Identity $user -Property MemberOf | Select-Object -ExpandProperty MemberOf | Where-Object { $_ -in $groups }
if ($CheckMembership) {
Start-Process "http://www.example.com"
}
您需要确保您的组列表是可分辨名称列表,但除此之外,这会将AD查询的数量减少到1。
答案 3 :(得分:0)
任何依赖Get-AD___
的东西都需要RSAT工具来获取ActiveDirectory模块,这对于最终用户工作站来说是不太可能的假设,如@Rohin Sidharth的评论。
@James C.目前接受的答案将不会处理递归组成员资格(需要-Recursive
参数),但也涉及列出两个组的所有成员 - 想象一下这是十亿每个小组的成员 - 并且它有不良的阵列添加习惯。
@Bacon Bits回答获得用户的群组成员资格,这样可以更好地获得更少的数据'但仍然不会处理递归组成员资格,仍然依赖于ActiveDirectory模块。
为了避免使用RSAT,可以使用ADSI之类的东西 - 它由System.DirectoryServices.AccountManagement包装。由Richard Siddaway讨论here。
这有一个很好的方法来列出一个用户的群组成员,这看起来很糟糕 - 从类似的问题here收到Terry Tsay的C#答案,我将他的代码移植到这个但是我专注于当前用户并默认包含通讯组:
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
Function IsUserInGroup([string] $groupName)
{
# Remove DOMAIN\ from the start of the groupName.
$groupName = $groupName -replace '^.*\\'
# Get an AD context for the current user's domain
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList 'Domain', $ENV:USERDOMAIN
# Find the current user account in AD, and refresh the security and distribution groups
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($context, 'SAMAccountName', $env:USERNAME)
$userEntry = [System.DirectoryServices.DirectoryEntry] $user.GetUnderlyingObject()
$userEntry.RefreshCache(@('tokenGroupsGlobalAndUniversal'))
# Get all the security and distribution groups the user belongs to, including nested memberships
$usersGroupSIDs = foreach ($sid in $userEntry.Properties.tokenGroupsGlobalAndUniversal.Value)
{
New-Object System.Security.Principal.SecurityIdentifier -ArgumentList $sid, 0
}
# Get the AD details for the group to test, and test membership
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, 'SamAccountName', $groupName)
$usersGroupSIDs.Contains($group.Sid)
}
e.g。
PS C:\> IsUserInGroup 'parent-nested-group-here'
True
它不是简洁或简单的,但它应该处理更多条件,减少AD连接开销,特别是当组成员数量增加时,只需使用.Net框架就需要额外的模块。
然后你可以修改它来做
$group2 = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, 'SamAccountName', $group2Name)
$usersGroupSIDs.Contains($group.Sid) -or $usersGroupSIDs.Contains($group2.Sid)
答案 4 :(得分:-1)
你可以添加一个foreach
循环,但是这会使一个非常小而简单的脚本复杂化。
我所做的最多就是将两个小组的成员资格加在一起......
$user = $env:username
$group1 = "examplegroup1"
$group2 = "examplegroup2"
if (Test-Connection "examplenetwork" -Quiet)
{
$members = Get-ADGroupMember -Identity $group1 | Select -ExpandProperty SamAccountName
$members += Get-ADGroupMember -Identity $group2 | Select -ExpandPropertySamAccountName
If ($members -contains $user) {Start-Process "http://www.example.com"}
}