【问题标题】:Local or remote execution of powershell script with generic parameters使用通用参数本地或远程执行 powershell 脚本
【发布时间】:2015-10-08 17:09:17
【问题描述】:

在开发团队中,我希望开发人员在本地或我们的测试平台远程执行相同的测试脚本。

这是我想用作每个脚本的前提

# Test local/remote execution by reading C:\ directory
param(
    [switch] $verbose,
    [switch] $remote,
    [string] $ip,
    [string] $user,
    [string] $password
    #Add here script specific parameters
)

Write-Host "Command invokation incoming parameter count : " $psboundparameters.count

if ($remote) {
    $Params = @{}
    $RemoteParams = @{}
    $pass = ConvertTo-SecureString -String $password -AsPlainText -Force 

    $Params.Credential = new-object -TypeName System.management.automation.PSCredential -argumentlist $user, $pass
    $Params.ComputerName = $ip
    $Params.FilePath = $MyInvocation.MyCommand.Name
    $null = $psboundparameters.Remove('remote')
    $null = $psboundparameters.Remove('ip')
    $null = $psboundparameters.Remove('user')
    $null = $psboundparameters.Remove('password')

    foreach($psbp in $PSBoundParameters.GetEnumerator())
    {
        $RemoteParams.$($psbp.Key)=$psbp.Value
    }
    Write-Host $RemoteParams
    Invoke-Command @Params @Using:RemoteParams
    Exit 
}

Write-Host "Command execution incoming parameters count : "    $psboundparameters.count

# Here goes the test 
Get-ChildItem C:\

但是,当我执行此操作时,出现以下错误:

Invoke-Command : A positional parameter cannot be found that accepts argument '$null'.

似乎 @Using:RemoteParams 不是这样做的正确方法,但我在这里很迷茫。 提前致谢

【问题讨论】:

    标签: powershell remote-access invoke-command splat


    【解决方案1】:

    以下是我对能够使用命名参数进行本地和远程执行的问题的看法:

    $IP = '192.168.0.1'
    $User = 'Test User'
    $Password = 'P@ssW0rd!' 
    
    $params = @{
    IP = $IP
    User = $User
    Password = $Password
    }
    
    $command = 'new-something'
    
    $ScriptBlock = [Scriptblock]::Create("$command $(&{$args} @Params)")
    

    从参数哈希表开始,使用局部变量,然后使用:

    [Scriptblock]::Create("$command $(&{$args} @Params)")
    

    创建命令的脚本块,内联参数和已扩展的值。现在该脚本块已准备好在本地运行(通过调用& 或点源),或远程使用Invoke-Command

    $ScriptBlock
    new-something -IP: 192.168.0.1 -User: Test User -Password: P@ssW0rd!
    

    不需要$Using:-argumentlist 的范围。

    编辑:这是一个使用脚本而不是单个命令的示例:

    $path = 'c:\windows'
    $filter = '*.xml'
    
    $Params = 
    @{
       Path = $path
       Filter = $filter
      }
    
    $command = @'
    {
      Param (
        [String]$path,
        [String]$Filter
       )
    
     Get-childitem -Path $path -Filter $filter
    }
    '@
    
    $ScriptBlock = [Scriptblock]::Create(".$command $(&{$args} @Params)")
    

    在本地运行:

     Invoke-Command $ScriptBlock
    

    或者只是:

     .$ScriptBlock
    

    远程运行:

     Invoke-Command -Scriptblock $ScriptBlock -ComputerName Server1
    

    【讨论】:

    • 这个scriptlet背后的想法是在每个测试脚本的开头使用它,这样用户就不必编写一个重复脚本参数的脚本块。我希望它尽可能通用,真正的参数列表在命名参数块中只声明一次。例如,下一步将是发现“文件类型”参数并在脚本块中准备它们。
    • 如果我对注释的理解正确,您担心用户脚本作为 $command 嵌入到示例中。您可以通过对脚本文件执行 Get-Content 并使用脚本的路径作为参数来轻松填充它。您不能在他们尝试过的 splat 中使用 $using。必须在脚本中的每个变量引用上指定它,但如果你这样做,那么脚本就不能在本地工作。这为您提供了一个脚本块,可以在本地或远程工作,而无需在脚本中操作变量范围。
    猜你喜欢
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    相关资源
    最近更新 更多