Powershell将函数传递给远程命令

时间:2015-05-18 13:21:43

标签: powershell

我正在尝试将本地函数传递给远程代码,但没有取得任何成功。以下是我的代码。

#variables defined over here
...
function comparehash ($source, $destination)
{
    $sourcefiles = @{}
    ...
}

$securePassword = ConvertTo-SecureString -AsPlainText -Force $Password 
$cred = New-Object System.Management.Automation.PSCredential $Username, $securePassword
$session = New-PSSession -ComputerName $srv -port 22 -Credential $cred  –Authentication CredSSP
Invoke-Command -Session $session -ScriptBlock { 
    param( $source, $destination, $application)
    #Write-Host "This is" $source
    # Take backup of the site first
    Copy-Item $source\$application $destination -Recurse -force
    ${function:comparehash}
}  -ArgumentList $site_path_local, $backup_path, $app
Remove-PSSession -Session $session

此代码将源文件复制到目标。已创建函数以验证复制文件的md5总和。当我运行脚本脚本运行正常但它没有调用功能代码。是否还有其他需要做的事情来调用函数?

更新

Invoke-Command -Session $session -ScriptBlock { 
    param( $source, $destination, $application, $fundef, $comparefunc )
    Write-Host "This is" $source, $destination
    # Take backup of the site first
    #Copy-Item $source\$application $destination -Recurse -force
    [ScriptBlock]::($comparefunc).Invoke($source,$destination)
    #comparehash $site_path_local $backup_path
}  -ArgumentList $site_path_local, $backup_path, $app, ${function:comparehash}
Remove-PSSession -Session $session

以上代码引发以下错误:

PS C:\Windows\system32> C:\Users\vijay.patel\Documents\myscripts\Env_Refresh.ps1
This is F:\inetpub F:\Env_Backup\Refresh_Backup\
You cannot call a method on a null-valued expression.
    + CategoryInfo          : InvalidOperation: (Invoke:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
    + PSComputerName        : 172.16.82.124

2 个答案:

答案 0 :(得分:1)

由于函数是在您自己的本地范围内定义的,因此您也必须将其传递给远程会话。通过测试,它似乎以字符串形式传递,但您可以使用[scriptblock]::Create()来重新创建"它在远程会话中:

Invoke-Command -Session $session -ScriptBlock { 
    param( $source, $destination, $application, $comparefunc)
    # do stuff
    # Now invoke the function that was provided
    [ScriptBlock]::Create($comparefunc).Invoke($source,$destination)
} -ArgumentList $site_path_local, $backup_path, $app, ${function:comparehash}

答案 1 :(得分:0)

我发现$ Using命令可以在这里成为您的朋友。如果将远程PSSession保持打开状态,则可以一次转移所有需要的功能,然后调用最后一个调用/使用这些功能的脚本块。

function comparehash($source, $destination)
{
    Write-Output "I like hash";
    if( $source -eq $destination) { PackThePipe $source; }
}

function PackThePipe($hash)
{
    Write-Output "Pushing $hash through the pipe";
}


$session = New-PSSession -ComputerName $srv -port 22 -Credential $cred  –Authentication CredSSP

#create the functions we need remotely
Invoke-Command $session { Invoke-Expression $Using:function:comparehash.Ast.Extent.Text; }
Invoke-Command $session { Invoke-Expression $Using:function:PackThePipe.Ast.Extent.Text; }

#call the scriptblock that utilizes those functions
Invoke-Command $session { $s = "12345"; $d="12345"; comparehash $s $d; }

Remove-PSSession $session;