Имею следующий модуль.
Я запутал хэш-таблицу для защиты конфиденциальной информации, но в ней есть набор значений, которые определяют контроллер домена, DN домена, имя пользователя домена и т. Д .:
function set-domparams {
Param(
[Parameter(Mandatory = $true,Position=0)]
[string]$domain,
[Parameter(Mandatory = $true,Position=1)]
[string[]]$username,
[Alias("pass","p")]
[Parameter(Mandatory = $false,Position=2)]
$password,
[Parameter(Mandatory = $true,Position=3)]
[ValidateSet("Y","N")]
[string]$cyberArk
)
Invoke-Expression -Command:'cmd.exe /c klist purge' | Out-Null
function Get-Creds($domain,$user,$password) {
if (!($password)) {$password = Read-Host "Enter $domain password" -AsSecureString}
Invoke-Expression -Command:'cmd.exe /c klist purge' | Out-Null
$creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,$password
return $creds
}
$doms = @{
'domain1.com' = @{'serverDC' = "somesvalidDC.fqdn.com";'searchBase' = "DC=somesvalidDC,DC=fqdn,DC=com";'suffix' = "domain1.com"; 'TSMserver' = "127.0.0.1"; 'NetBIOS' = "domain1"; 'SCOM' = "somescomserver.com";'AdminSuffix' = "_admin"}
'domain2.com' = @{'serverDC' = "somesvalidDC.fqdn.com";'searchBase' = "DC=somesvalidDC,DC=fqdn,DC=com";'suffix' = "domain2.com"; 'TSMserver' = "127.0.0.1"; 'NetBIOS' = "domain2"; 'SCOM' = "somescomserver.com";'AdminSuffix' = ".adm"}
}
if ((!$cyberArk) -or ($cyberArk -eq 'N')) {
$global:fetchCreds = Get-Creds -domain $domain -user $username -password $password
} else {
$CyberArkUser = "cyberarkdom\" + $username
$CyberArkdomain = 'cyberarkdom.int'
$global:fetchCreds = Get-Creds -domain $CyberArkdomain -user $CyberArkUser -password $password
}
$global:adminsuffix = $doms.$domain.AdminSuffix
$global:user = $doms.$domain.NetBIOS + "\" + $username + $adminsuffix
$global:dc = $doms.$domain.serverDC
$global:DomNBT = $doms.$domain.NetBIOS
$global:searchbase = $doms.$domain.searchBase
$global:suffix = $doms.$domain.suffix
$global:TSMserver = $doms.$domain.TSMserver
$global:scom = $doms.$domain.scom
}
Я много раз использовал это в сценариях, и он работает, но в настоящее время у меня возникает странная проблема при попытке выполнить операцию с несколькими доменами в новом сценарии:
Param(
[Parameter(Mandatory = $true)]
[ValidateSet("Y","N")]
[string]$cyberArk
)
$userprompt = Read-Host "Enter username"
$userpass = Read-Host "Enter $domain password" -AsSecureString
$domainlist = @('domain1.fqdn.co', 'anotherdomain.com', 'differesntforest3.com.au')
foreach ($domain in $domainlist) {
$results = ""
set-domparams -domain $domain -username $userprompt -password $userpass -cyberArk $cyberArk
$results = Get-ADGroup -Server $DC -Credential $fetchCreds -Filter * |
where {$_.Name -like "*-DelAdmin-Servers*"} |
select Name, SamAccountName
foreach ($result in $results) {
[PSCustomObject]@{
Name = $result.Name
domain = $domain
samaccountname = $result.SamAccountName
}
}
}
Я получаю следующую ошибку, когда список доменов содержит домены из разных лесов (пароль одинаков для всех доменов):
Get-ADGroup : The server has rejected the client credentials.
At E:\Scripts\get-testrun.ps1:16 char:16
+ ... $results = Get-ADGroup -Server $DC -Credential $fetchCreds -Filter * ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [Get-ADGroup], AuthenticationException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.Security.Authentication.AuthenticationException,Microsoft.ActiveDirectory.Management.Commands.GetADGroup
При запуске в качестве одного лайнера против любого из этих доменов по отдельности, модуль работает и аутентифицируется нормально, возвращая все глобальные переменные и выполняя запрос в скрипте без ошибок.
Что мне не хватает?
$fetchCreds не определен во втором скрипте ...





Как упоминалось в комментариях, оскорбительная строка - ваш Get-ADGroup. В частности, следующее:
Get-ADGroup -Server $DC -Credential $fetchCreds -Filter *
Во втором, текущем скрипте вы не определяете $fetchCreds. если у вас есть аналогичные другие скрипты, вероятно, вы либо назначаете что-то напрямую, либо используете $global:fetchCreds, поскольку он готовится в вашем первом скрипте.
$ fetchcreds - это глобальная переменная, которая определяется после передачи необходимых параметров в get-adgroup и может рассматриваться как объект учетных данных при вводе $ fetchcreds после запуска в одном домене в качестве одного лайнера.
Это звучит бессмысленно. Если он определен только ПОСЛЕ передачи Get-ADGroup, вы не сможете использовать его для Get-ADGroup. Кроме того, да, он определен в глобальной области видимости. Приставку $global пробовали? Может быть, по какой-то причине ваш вызов приводит к тому, что автоматическое расширение не выполняется?
Исправление - ДО (опечатка). Это работает с тем же кодом за пределами цикла for для любого отдельного домена, поэтому происходит что-то странное, что я не могу понять, размещая здесь в надежде, что есть что-то очевидное, что я могу упустить.
Вы смотрели содержимое глобальных переменных в цикле? Если да, то каков был результат? Они содержат ожидаемые значения? Ваше приглашение $userpass содержит неопределенную переменную $domain. Также Get-Creds всегда вызывается и имеет собственное приглашение. Вы получаете set-domparams с помощью Import-Module или это часть того же файла? В качестве примечания: вы можете использовать свой where в качестве фильтра для Get-ADGroup.
Я понял, что в логике функции, которую я использовал, была ошибка.
После исправления он успешно работает с любым количеством доменов (то есть с массивом из множества разных массивов).
function set-domparams {
Param(
[Parameter(Mandatory = $true,Position=0)]
[string]$domain,
[Parameter(Mandatory = $true,Position=1)]
[string[]]$username,
[Alias("pass","p")]
[Parameter(Mandatory = $false,Position=2)]
$password,
[Parameter(Mandatory = $true,Position=3)]
[ValidateSet("Y","N")]
[string]$cyberArk
)
function Get-Creds($domain,$user,$password) {
Invoke-Expression -Command:'cmd.exe /c klist purge' | Out-Null
If (!($password)) {$password = Read-Host "Enter $domain password" -AsSecureString}
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$password
return $creds
}
$doms = @{
'domain1.com' = @{'serverDC' = "somesvalidDC.fqdn.com";'searchBase' = "DC=somesvalidDC,DC=fqdn,DC=com";'suffix' = "domain1.com"; 'TSMserver' = "127.0.0.1"; 'NetBIOS' = "domain1"; 'SCOM' = "somescomserver.com";'AdminSuffix' = "_admin"}
'domain2.com' = @{'serverDC' = "somesvalidDC.fqdn.com";'searchBase' = "DC=somesvalidDC,DC=fqdn,DC=com";'suffix' = "domain2.com"; 'TSMserver' = "127.0.0.1"; 'NetBIOS' = "domain2"; 'SCOM' = "somescomserver.com";'AdminSuffix' = ".adm"}
}
$global:adminsuffix = $doms.$domain.AdminSuffix
$global:dc = $doms.$domain.serverDC
$global:DomNBT = $doms.$domain.NetBIOS
$global:searchbase = $doms.$domain.searchBase
$global:suffix = $doms.$domain.suffix
$global:TSMserver = $doms.$domain.TSMserver
$global:scom = $doms.$domain.scom
If ((!$cyberArk) -or ($cyberArk -eq 'N')) {
$global:user = $doms.$domain.NetBIOS + "\" + $username + $adminsuffix
$global:fetchCreds = Get-Creds -domain $domain -user $user -password $password
}
Else {
$global:User = "corpau\" + $username
$CyberArkdomain = 'corpau.wbcau.westpac.com.au'
$global:fetchCreds = Get-Creds -domain $CyberArkdomain -user $user -password $password
}
}
Конечно, это не самая лучшая написанная функция, но она выполняет ту работу, для которой была предназначена.
Пожалуйста, подумайте о предоставлении MCVE (минимальный, полный и проверяемый пример) или как можно более близком к нему. В вашем коде много отвлекающих элементов (либеральное использование глобальных переменных, ненужное использование
Invoke-Expression).