Reputation: 33
Basically, I'm loading the XML from my local machine, and then I'm trying to save it on a remote machine using Invoke-Command.
I know I can use Copy-item via UNC path, but it takes too long on some machines, and Invoke-Command is faster - I tested this already.
However, I think I'm passing the argument wrong?
The error I get is:
Method invocation failed because [System.String] does not contain a method named 'Save'.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
+ PSComputerName : -
This is how I'm passing it:
foreach ($serverPath in $serverLocations) {
if ($null -ne $serverPath) {
$generatedPath = "$(Get-Location)\Generated.ManageSQLJobs.xml"
[Xml]$generatedFile = Get-Content $generatedPath
Write-Log "INFO" "Checking on $serverPath" $ExecutionLogFullPath
$testPath = Invoke-Command -ComputerName "$serverPath" -ArgumentList [Xml]$generatedFile -ScriptBlock {
param (
$value
)
Test-Path -Path "C:\AppData\MonitoringConfig\"
if (!$testPath) {
$destinationPath = New-Item -Path "C:\AppData\" -Name "MonitoringConfig" -ItemType Directory
}
if ($testPath) {
$destinationPath = "C:\AppData\MonitoringConfig"
#Write-Log "INFO" "Exists on $serverPath." $ExecutionLogFullPath
}
$GetPathToDeleteXML = "C:\AppData\MonitoringConfig\Generated.ManageSQLJobs.xml"
if (Test-Path -Path $GetPathToDeleteXML) {
Remove-Item -Path * #-Filter Generated.ManageSQLJobs.xml
}
$GetPathForXML = "C:\AppData\MonitoringConfig\Generated.ManageSQLJobs.xml"
$value.Save($GetPathForXML.fullname)
}
}
}
Upvotes: 1
Views: 179
Reputation: 440142
-ArgumentList [Xml]$generatedFile
should be (note the (...)
):
-ArgumentList ([Xml]$generatedFile)
[Xml]$generatedFile
isn't recognized as an expression, because when PowerShell parses in argument mode (commands with arguments, shell-style), an initial [
isn't special.
In effect, your argument is interpreted as an expandable string, i.e. as if you had passed
"[Xml]$generatedFile"
.
Therefore, $value
in your remotely executed script block received a [string]
instance, not an [xml]
instance, and strings don't have a .Save()
method, which explains the error message.
Enclosing your argument in (...)
forces its interpretation as an expression.
See this answer for a comprehensive overview of how PowerShell parses unquoted tokens in argument mode.
A general caveat re passing complex objects as arguments to code executed remotely / in background jobs:
Arguments passed to remote / background script blocks must undergo XML-based serialization and deserialization, because they pass computer / process boundaries.
Only a limited set of known types are deserialized faithfully (deserialized as the original type), others are emulated.
While [xml]
instances, [string]
instances and .NET primitive types such as [int]
are faithfully deserialized, most other types are not.
See this answer for more information.
Upvotes: 1