Powershell Значение аргумента path равно NULL
Я разработал файл PS1, который будет отвечать за применение исправлений SQL Server на основе списка серверов. Таким образом, он прочитает текстовый файл со всеми серверами, которые мне нужно исправить и применить Patch. Я решил использовать PARAM для "Исходной папки" (где я получу список серверов и запись вывода); "Папка назначения" (где я смогу запустить патч), "Файл" (имя патча), "Экземпляр" (экземпляр SQL Server, на котором я буду запускать обновление патча). Когда я начинаю запускать команды ниже, он может читать список серверов (так, 1-й PARAM в порядке), но он возвращает ошибку ниже процесса прерывания. Чего не хватает или что я делаю не так в коде ниже?
PS: Я также хотел бы использовать Try...Catch для записи сообщения в выходной файл. Я правильно написал? Заранее спасибо!
[CmdletBinding()]
Param (
[Parameter(Mandatory=$True,Position=0)]
[string]$foldersource,
[Parameter(Position=1)]
[string]$folderdest,
[Parameter(Position=2)]
[string]$file,
[Parameter(Position=3)]
[string]$instance
)
foreach ($cluster in GC "$foldersource\Servers_List.txt")
{
$output = "Server: $cluster Patch Installation on: $(Get-Date -format 'u')"
try{
Invoke-Command -ComputerName $cluster -ScriptBlock
{
cd $folderdest
.\$file /X:$folderdest
Start-Sleep -s 10
.\SETUP.exe /action=patch /instancename=$instance /quiet /IAcceptSQLServerLicenseTerms
}
-ErrorAction Stop;
$output += " SUCCESS"
}
catch
{
$output += "Failed - $($_.exception.message)"
}
$output | Out-File -Append $foldersource\Patch_Result_Non_SP.txt
}
Как я запускаю команду выше: .\SQL_Server_install_non-Service_Pack_V2.ps1 "D:\Software\Patch" "D:\Software" "SQLServer2008R2-KB3045316-x64.exe" "MSSQLSERVER"
ERROR:
Cannot process argument because the value of argument "path" is null. Change the value of argument "path" to a non-null value.
+ CategoryInfo : InvalidArgument: (:) [Set-Location], PSArgumentNullException
+ FullyQualifiedErrorId : ArgumentNull,Microsoft.PowerShell.Commands.SetLocationCommand
+ PSComputerName :
The term '.\$file' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (.\$file:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName :
The term '.\SETUP.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (.\SETUP.exe:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName :
1 ответ
Вы должны передать свои аргументы либо через -ArgumentList
или через $using
конвенция к Invoke-Command
Командлет. Так как вы не делаете это таким образом $folderdest
, $file
будет нулевым в объеме Invoke-Command
scriptblock -> scriptblock определяет отдельную область видимости!
От Microsoft:
-ArgumentList
Предоставляет значения локальных переменных в команде. Переменные в команде заменяются этими значениями до запуска команды на удаленном компьютере. Введите значения в списке через запятую. Значения связаны с переменными в том порядке, в котором они перечислены. Псевдоним ArgumentList - Args.
Также ознакомьтесь с примерами из Invoke-Command
командлет через Get-Help Invoke-Command -Examples
,
Если вам не нравится ArgumentList
Решение вы также можете использовать удаленные переменные.
Кроме того, вы также должны определить абсолютный путь к вашему Setup.exe
!
Итак, ваш код должен выглядеть так:
....
Invoke-Command -ComputerName $cluster -ArgumentList $file, $folderdest, $instance -ScriptBlock
{
Param(
[string] $rFile,
[string] $rfileDest,
[string] $rInstance
)
# Remove Write-Host after the script block works fine -> Write-Host is only a quick and dirty way to dump the variables content
Write-Host $rFile
Write-Host $rfileDest
Write-Host $rInstance
cd $rfileDest
$someArgs = "/X:{0}" -f $rfileDest
Start-Process -FilePath $rFile -ArgumentList $someArgs -Wait -PassThru
Start-Sleep -s 10
$setupArgs = "action=patch /instancename={0} /quiet /IAcceptSQLServerLicenseTerms" -f $rInstance
Start-Process -FilePath ".\Setup.exe" -ArgumentList $setupArgs -Wait -PassThru
}
....
Надеюсь, это поможет.