Я пытаюсь составить список групп, которые имеют доступ к набору компьютеров / серверов в нашей организации, что касается отчетов о лицензиях MSDN ..: - /
основываю свою работу на записи блога Hey Scripting Guy о членстве в локальной группе: http://blogs.technet.com/b/heyscriptingguy/archive/2013/10/27/the-admin-s-first-steps-local-group-membership.aspx
Однако мне нужно проверить участников более чем в одной группе на каждом сервере. И вот неловкость, которую я не могу вспомнить раньше: при добавлении дополнительных параметров в раздел параметров функции невозможно получить ни одного из членов группы.
function Test-LocalSecurityGroups {
[CmdletBinding()]
param(
[parameter(
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = $env:COMPUTERNAME,
[parameter(
ValueFromPipelineByPropertyName=$true)]
[string[]]$Group
)
BEGIN {
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine
}
PROCESS{
foreach ($Computer in $ComputerName) {
Write-Verbose "Connecting to $Computer"
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $Computer
$idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, 'Administrators')
$group.Members | select @{N='Server'; E={$computer}}, @{N='Group Name'; E={$group.Name}}, @{N='Domain'; E={$_.Context.Name}}, samaccountName
} # end foreach
} # end PROCESS
}
Вот несколько примеров использования, которое не работает (никакого результата не было):
PS D:\> Test-LocalSecurityGroups -ComputerName $env:COMPUTERNAME -Group "Administrator"
PS D:\>
PS D:\> $env:COMPUTERNAME, "Computer1" | Test-LocalSecurityGroups
PS D:\>
PS D:\> $env:COMPUTERNAME, "Computer1" | Test-LocalSecurityGroups -Group "Administrators"
PS D:\>
Однако это даже без НИЧЕГО не делая с переменной Group. Если я закомментирую эту часть:
[parameter(
ValueFromPipelineByPropertyName=$true)]
[string[]]$Group
)
Работает нормально .. Итак, может ли кто-нибудь мне объяснить, почему это происходит? У меня есть более обширная структура вокруг всей функции, но у меня такая же проблема, когда она изолирована, поэтому я делаю вывод, что либо я забываю что-то жизнеспособное о PowerShell, либо что-то происходит в проводном соединении ...
Ошибок нет, список пользователей просто пустой. У меня такая же проблема при запуске из PowerShell ISE, а также при прямой загрузке в оболочку напрямую (как получение точек, так и вставка функции в оболочку.
Альтернативный вариант - сделать это с двумя отдельными функциями, а ЗАТЕМ сравнить результаты в третьей функции. Но это действительно не лучшее решение, не так ли? :-p DRY FTW!
Имена переменных PowerShell: нечувствительный к регистру.
Другими словами: $Group.Equals($group)
В рамках PROCESS
блок, когда вы назначаете GroupPrincipal
Возражать $group
, вы фактически пытаетесь перезаписать существующий $Group
переменная параметра.
Просто измените имя встроенной переменной и добавьте еще один цикл для перебора каждого имени группы:
foreach ($Computer in $ComputerName) {
Write-Verbose "Connecting to $Computer"
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $Computer
$idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
foreach($groupName in $Group)
{
$groupPrincipal = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, $groupName)
$groupPrincipal.Members | select @{N='Server'; E={$computer}}, @{N='Group Name'; E={$groupPrincipal.Name}}, @{N='Domain'; E={$_.Context.Name}}, samaccountName
}
} # end foreach