#windows #amazon-web-services #powershell
#powershell #переменные #invoke-command
Вопрос:
Мне нужно получать журналы событий с некоторых серверов, и я не хочу читать учетные данные для каждого найденного сервера.
Я пытался передать свои переменные с помощью параметра ArgumentList, но у меня ничего не получается.
Это мой код:
$User = Read-Host -Prompt "Enter Username"
$Password = Read-Host -Prompt "Enter Password" -AsSecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
Get-ADComputer -Filter "OperatingSystem -Like '*Server*'" | Sort-Object Name |
ForEach-Object{
if($_.Name -like '*2008*'){
Invoke-Command -ComputerName $_.Name -ArgumentList $User, $UnsecurePassword -ScriptBlock {
net use P: \Serverdir1dir2 /persistent:no /user:$User $UnsecurePassword
Get-EventLog -LogName System -After (Get-Date).AddHours(-12) -EntryType Error, Warning | format-list |
out-file P:EventLog_$env:COMPUTERNAME.log
net use P: /delete /yes
}
}
}
Как я могу использовать переменные в скриптовом блоке Invoke-Command?
Ответ №1:
В качестве альтернативы вы можете использовать область $Using:
видимости. Смотрите Пример 5 по этой ссылке.
Пример:
$servicesToSearchFor = "*"
Invoke-Command -ComputerName $computer -Credential (Get-Credential) -ScriptBlock { Get-Service $Using:servicesToSearchFor }
При $Using:
этом вам не нужны -ArgumentList
параметр и param
блок в scriptblock.
Комментарии:
1. Это работает намного лучше, чем
param
и тому подобное! Спасибо!
Ответ №2:
Либо вы объявляете параметры в начале вашего скриптового блока:
{
param($user,$unsecurepassword)
net use P: \Serverdir1dir2 /persistent:no /user:$User $UnsecurePassword
Get-EventLog -LogName System -After (Get-Date).AddHours(-12) -EntryType Error, Warning | format-list |
out-file P:EventLog_$env:COMPUTERNAME.log
net use P: /delete /yes
}
Или вы получаете доступ к своим аргументам с помощью $args
переменной:
#first passed parameter
$args[0]
#second passed parameter
$args[1]
....
Документация: MSDN
Комментарии:
1. Просто убедитесь, что ваши переменные в
param()
совпадают с теми, которые вы передаете через-ArgumentList
. Я узнал это на собственном опыте, когда мой $computer продолжал отображаться как мой идентификатор пользователя, lol
Ответ №3:
При использовании ScriptBlock
with Invoke-Command
предполагается, что все переменные внутри ScriptBlock
определены в удаленном сеансе при его подключении, поэтому он недоступен в вашем текущем блоке скрипта как обычная форма использования переменных!
Если вам нужно использовать переменную, заполненную внутри вашего скрипта на удаленной стороне, вам следует использовать Using
модификатор области видимости для идентификации этой локальной переменной в среде удаленного управления.
Смотрите Пример 9 на: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-7.3
измените свой код следующим образом:
...
ForEach-Object{
if($_.Name -like '*2008*'){
Invoke-Command -ComputerName $_.Name -ArgumentList $User, $UnsecurePassword -ScriptBlock {
net use P: \Serverdir1dir2 /persistent:no /user:$Using:User $Using:UnsecurePassword
Get-EventLog -LogName System -After (Get-Date).AddHours(-12) -EntryType Error, Warning | format-list |
out-file P:EventLog_$env:COMPUTERNAME.log
net use P: /delete /yes
}
}