【问题标题】:Powershell Value of argument path is NULL参数路径的Powershell值为NULL
【发布时间】:2018-04-06 00:44:16
【问题描述】:

我已经开发了一个 PS1 文件,它将负责基于服务器列表应用 SQL Server 补丁。因此,它将读取包含我需要修补和应用补丁的所有服务器的文本文件。 我决定将 PARAM 用于“源文件夹”(我将在其中获取服务器列表并记录输出); “目标文件夹”(我可以在其中运行补丁)、“文件”(补丁名称)、“实例”(我将运行补丁更新的 SQL Server 实例)。 当我开始运行下面的命令时,它能够读取服务器列表(所以,第一个 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        : 

【问题讨论】:

  • try catch 使用是正确的
  • 谢谢@Moerwald! :)
  • 我添加了一个答案,包括可能的解决方案。如果答案是正确的,请将其标记为正确的。谢谢。

标签: sql-server powershell path patch service-pack


【解决方案1】:

您必须通过-ArgumentList$using 约定将参数传递给Invoke-Command cmdlet。由于您没有这样做$folderdest$fileInvoke-Command 脚本块的范围内将为空-> 脚本块定义了一个单独的范围!

来自Microsoft

-参数列表

在命令中提供局部变量的值。在远程计算机上运行命令之前,命令中的变量会被这些值替换。在逗号分隔的列表中输入值。值按它们列出的顺序与变量相关联。 ArgumentList 的别名是 Args。

还可以通过Get-Help Invoke-Command -Examples 查看Invoke-Commandcmdlet 的示例。

如果您不喜欢ArgumentList 解决方案,您也可以使用remote variables

此外,您还应该定义一个绝对路径到您的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

}
....

希望对您有所帮助。

【讨论】:

  • 嗨@Moerwald!这很棒!我不知道 ArgumentList。感谢分享:)
  • 我已更新代码,但错误已更改。我试过自己调试,但是一旦我什至不知道 ArgumentList,我就无法解决它。如果你能再帮我一次,我真的很感激 :) 跟随,新代码和错误: Invoke-Command -ComputerName $cluster -ArgumentList $file, $folderdest -ScriptBlock{ Param( [string]$f, [string ]$fDest ) cd $fDest .\$f /X:$fDest Start-Sleep -s 10 D:\Software\SETUP.exe /action=patch /instancename=$instance /quiet /IAcceptSQLServerLicenseTerms}
  • 错误:术语“.\$f”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,如果包含路径,请验证路径是否正确并重试。
  • 还有一个问题:我不能使用 $fDest 作为 SETUP.EXE 的路径吗?它只适用于绝对路径吗?谢了!
  • @AdemirP:对不起。当然,您可以使用$fDest 作为 Setup.exe 的路径 -> 我的错误 -> 我会更新答案。关于.\$fproblem,$f 的内容似乎指向了一些不可执行的东西。您可以通过脚本块中的Write-Host $f 转储内容。
猜你喜欢
  • 1970-01-01
  • 2016-12-23
  • 2017-10-01
  • 2021-01-16
  • 2023-04-02
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
相关资源
最近更新 更多