Как передать переменную в блок Scriipt для использования с командой Invoke, которая вызовет исполняемый файл, принимающий переменную в качестве параметра переключения

#powershell #variables #powershell-remoting #invoke-command #start-process

Вопрос:

Я пытаюсь создать универсальный скрипт, который будет обрабатывать файлы реестра в списке удаленных серверов. Сценарий будет принимать ввод пути/имени файла для обработки и списка серверов для его обработки. Копирует файл .reg на удаленный сервер, а затем пытается обработать файл .reg на удаленном сервере. Чтобы сделать его универсальным для использования с любым файлом .reg, я хочу передать путьимя файла для обработки в переменной в блоке сценария. Я видел примеры передачи именованных переменных и позиционных параметров, но это, похоже, не соответствует моим требованиям. Я попытался создать содержимое блока сценария как тип блока сценариев и вызвать его, но это не работает. Большинство ошибок, которые я получаю, связаны с неверным синтаксическим анализом, неоднозначным параметром и т. Д. Я видел пару рабочих примеров, в которых путь/имя файла .reg жестко закодированы, но это противоречит цели того, что я пытаюсь выполнить. Я попробовал команду Invoke-с помощью сеанса и переменной-ComputerName, чтобы попробовать команду :using:» без успеха. Есть ли какой-либо способ передать переменную, которая в основном является значениями командной строки (параметры переключения и путь к файлу/имя) для исполняемого файла в блоке сценариев, или я делаю это неправильно? В приведенном ниже коде я пересекаю домены, поэтому мне приходится открывать сеанс для этих серверов, чтобы создать каталог, если он не существует.

     while ($true)
{
    $regFile = Read-Host -Prompt "Enter the path amp; name of registry file to be processed"
    If(Test-Path -Path $regFile) { break }

    Write-Host "You must enter valid path amp; filename of a registry file to process."    
}

$servers = Get-Content D:MLBScriptsservers.txt
$fileNm = [System.IO.Path]::GetFileName($regFile)

$pass = ConvertTo-SecureString "blahblah" -AsPlainText -Force
$Creds = new-object -typename System.Management.Automation.PSCredential( "domainusername", $pass)

foreach ($server in $servers)
{
    $dirPath = ''
    $newfile = '\'   $server   'd$MLBRegFiles'   $fileNm
    
    if($server.ToLower().Contains("web"))
    {
        $Session = New-PSSession -ComputerName $server -Credential $Creds
 
        Invoke-Command -Session $Session -ScriptBlock { New-Item -ErrorAction SilentlyContinue -ItemType directory -Path D:MLBRegFiles }

        $newfile = "d:MLBRegFiles"   $fileNm
        Copy-Item $regFile -Destination $newfile -ToSession $Session -Force
        Remove-PSSession -Session $Session
    }
    else
    {
        $dirPath = "\$serverd`$MLBRegFiles"
        New-Item -ErrorAction SilentlyContinue -ItemType directory -Path $dirPath 

        $newfile = "\$serverd`$MLBRegFiles$fileNm"

        Copy-Item $regFile -Destination $newfile -Force

     }

     Invoke-Command -ComputerName $server -Credential $Creds -ScriptBlock {
         $args = "s/ $newfile"
         Start-Process -filepath "C:Windowsregedit.exe" -Argumentlist $args
     }
 
 

Комментарии:

1. $scriptblock = { $ArgList = '/s',$using:newfile; amp; 'c:windowsregedit.exe' $ArgList } может сработать.

2. Спасибо администраторам, но это не сработало. Сначала попробовал это почти так же, как вы ввели выше, но включил команду запуска процесса, и она ошиблась в команде «$using», которую можно использовать только с Invoke-Commnad.

3. Если цель состоит в том, чтобы обновить удаленный реестр удаленным файлом в той же системе, то мой пример работает. Я только что проверил это. Не используйте Start-Process . Поскольку вы используете /s свой regedit.exe , вы отказываетесь от использования графического интерфейса, который будет Start-Process бесполезен, ЕСЛИ вы не хотите выполнять асинхронно. Не следует определять $args как пользовательскую переменную, поскольку это автоматическая переменная в PowerShell. Если $using: ошибки, то вы, должно быть, используете PowerShell версии v2 или ниже, и было бы лучше пометить вопрос версией PowerShell.

4. Если $using: не работает из-за проблемы с версией, возможно, вы можете это сделать Invoke-Command -ComputerName $server -Credential $Creds -ScriptBlock { amp; "C:Windowsregedit.exe" $args } -ArgumentList '/s',$newfile

5. Спасибо @AdminOfThings. ты настоящий мужчина. Это действительно успешно сработало. Извините за неправильное понимание вашего предыдущего комментария. Это именно то, что я искал,