2015-10-08 207 views
0

在開發團隊中,我希望具有相同的測試腳本,由開發人員在本地執行,或者由我們的測試平臺遠程執行。使用通用參數本地或遠程執行powershell腳本

這裏是我想爲前提,以使用爲每個腳本

# 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不是這樣做的正確方法,但我很迷茫。 在此先感謝

回答

0

這裏是我採取的是能夠使用命名參數做本地和遠程執行的問題:

$IP = '192.168.0.1' 
$User = 'Test User' 
$Password = '[email protected]!' 

$params = @{ 
IP = $IP 
User = $User 
Password = $Password 
} 

$command = 'new-something' 

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

先從參數哈希表,使用本地變量下,然後使用此:

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

創建該命令的腳本塊,其參數內聯和值已展開。現在腳本塊已準備好在本地運行(通過調用&或dot-sourcing),或者使用Invoke-Command遠程運行。

$ScriptBlock 
new-something -IP: 192.168.0.1 -User: Test User -Password: [email protected]! 

沒有與$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 
+0

這個scriptlet背後的想法是在每個測試腳本的開始處使用它,以便用戶不必編寫重複腳本參數的scriptblock。我希望它儘可能通用,並且在命名參數塊中只聲明一次真實參數列表。例如,下一步將發現「文件類型」參數並在腳本塊中進行準備。 – FoxAlfaBravo

+0

如果我正確理解評論,則擔心用戶腳本作爲$命令嵌入在示例中。您可以通過在腳本文件上執行Get-Content並使用腳本的路徑作爲參數來輕鬆填充。你不能在你嘗試的方式中使用$ splat。它必須在腳本中的每個變量引用上指定,但如果你這樣做,那麼腳本不能在本地工作。這爲您提供了一個腳本塊,可以在本地或遠程工作,而無需操作腳本中的變量作用域。 – mjolinor

相關問題