简体   繁体   English

Powershell参数路径的值为NULL

[英]Powershell Value of argument path is NULL

I've developed a PS1 file which will be responsible to apply SQL Server Patches, based on a Server List. 我已经基于服务器列表开发了一个PS1文件,该文件将负责应用SQL Server补丁。 So, it'll read a text file with all servers I need to patch and apply Patch. 因此,它将读取一个文本文件,其中包含我需要修补和应用Patch的所有服务器。 I've decided using PARAM for "Source Folder" ( where I'll get Server List and record output ); 我决定将PARAM用作“源文件夹”(我将在其中获取服务器列表并记录输出); "Destination Folder" ( where I'll be able to run patch ), "File" ( name of patch ), "Instance" ( SQL Server Instance which I'll be running Patch update ). “目标文件夹”(我将在其中运行补丁程序),“文件”(补丁程序的名称),“实例”(我将运行补丁程序更新的SQL Server实例)。 When I start to run commands below, it's able to read Servers List ( so, 1st PARAM is ok ), but, it returns the error below aborting process. 当我开始在下面运行命令时,它可以读取服务器列表(因此,第一个PARAM可以),但是,它在中止过程以下返回错误。 What is missing or what am I doing wrong on code below? 以下代码缺少什么或我在做什么错?

PS.: I also would like to use Try...Catch to record a message on the output file. PS .:我也想使用Try ... Catch在输出文件上记录一条消息。 Did I write it correctly? 我写的正确吗? Thanks in advance! 提前致谢!

[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
} 

How I'm running command above: .\\SQL_Server_install_non-Service_Pack_V2.ps1 "D:\\Software\\Patch" "D:\\Software" "SQLServer2008R2-KB3045316-x64.exe" "MSSQLSERVER" 我如何在上面运行命令:。\\ 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        : 

You've to pass your arguments either via -ArgumentList or via $using convention to the Invoke-Command cmdlet. 您必须通过-ArgumentList或通过$using约定将参数传递给Invoke-Command cmdlet。 Since you are not doing it that way $folderdest , $file will be null in the scope of the Invoke-Command scriptblock -> the scriptblock defines a seperate scope! 由于您没有以这种方式执行$folderdest ,因此$fileInvoke-Command $folderdest的范围内$folderdest >脚本块定义了单独的范围!

From Microsoft : 来自微软

-ArgumentList -ArgumentList

Supplies the values of local variables in the command. 在命令中提供局部变量的值。 The variables in the command are replaced by these values before the command is run on the remote computer. 在远程计算机上运行命令之前,命令中的变量将被这些值替换。 Enter the values in a comma-separated list. 在以逗号分隔的列表中输入值。 Values are associated with variables in the order that they are listed. 值按列出的顺序与变量关联。 The alias for ArgumentList is Args. ArgumentList的别名为Args。

Also checkout the exmamples of the Invoke-Command cmdlet via Get-Help Invoke-Command -Examples . 还可以通过Get-Help Invoke-Command -Examples检出Invoke-Command cmdlet的示例。

If you don't like the ArgumentList solution you can also use remote variables . 如果您不喜欢ArgumentList解决方案,则还可以使用远程变量

Additionally you should also define an absolute path to your Setup.exe ! 另外,您还应该定义Setup.exe的绝对路径!

So your code should look like: 因此,您的代码应如下所示:

....
 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

}
....

Hope that helps. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM