Powershell参数路径的值为NULL [英] Powershell Value of argument path is NULL

查看:455
本文介绍了Powershell参数路径的值为NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经根据服务器列表开发了一个PS1文件,该文件将负责应用SQL Server补丁.因此,它将读取一个文本文件,其中包含我需要修补和应用Patch的所有服务器. 我决定将PARAM用作源文件夹"(我将在其中获取服务器列表并记录输出); 目标文件夹"(我将在其中运行补丁程序),文件"(补丁程序的名称),实例"(我将运行补丁程序更新的SQL Server实例). 当我开始在下面运行命令时,它可以读取服务器列表(因此,第一个PARAM可以),但是,它在中止过程以下返回错误. 缺少什么,或者我在下面的代码中做错了什么?

I've developed a PS1 file which will be responsible to apply SQL Server Patches, based on a Server List. So, it'll read a text file with all servers I need to patch and apply Patch. I've decided using PARAM for "Source Folder" ( where I'll get Server List and record output ); "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 ). 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. What is missing or what am I doing wrong on code below?

PS .:我也想使用Try ... Catch在输出文件上记录一条消息.我写的正确吗? 提前致谢!

PS.: I also would like to use Try...Catch to record a message on the output file. 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
} 

我如何运行以上命令:.\ SQL_Server_install_non-Service_Pack_V2.ps1"D:\ Software \ Patch""D:\ Software""SQLServer2008R2-KB3045316-x64.exe""MSSQLSERVER"

How I'm running command above: .\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        : 

推荐答案

您必须通过-ArgumentList或通过$using约定将参数传递给Invoke-Command cmdlet.由于您未按照$folderdest的方式进行操作,因此$fileInvoke-Command脚本块的范围内为null->脚本块定义了单独的范围!

You've to pass your arguments either via -ArgumentList or via $using convention to the 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!

来自微软:

-ArgumentList

-ArgumentList

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

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.

还可以通过Get-Help Invoke-Command -Examples签出Invoke-Command cmdlet的示例.

Also checkout the exmamples of the Invoke-Commandcmdlet via Get-Help Invoke-Command -Examples.

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

If you don't like the ArgumentList solution you can also use remote variables.

此外,您还应该定义Setup.exe的绝对路径!

Additionally you should also define an absolute path to your 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

}
....

希望有帮助.

这篇关于Powershell参数路径的值为NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆