0
votes

I am trying to use the Invoke-Command to login to remote server and set to a location path and execute few commands. I am reading the data from a configuration xml in the powershell. My xml is of below type

<?xml version="1.0"?>
<Config>   
  <Action Name="Deploy">
            <CommandPath>C:\Program Files\Microsoft Sql server\110\</CommandPath>            
            <DeploymentServer>
                <Server Name = 'Server1'></Server>
                <Server Name = 'Server2'></Server>  
            </DeploymentServer>
            <Deployscript1 Name = 'listservices' > </Deployscript1>
            <Deployscript2 Name = 'script2' > </Deployscript2>
  </Action>
  <Action Name="Update">
    //few more nodes
  </Action>     
</Config>

I have tried the below powershell.

Set-ExecutionPolicy RemoteSigned

function RunConfiguration()
{

# get an array of 'Action' XmlElements
$actionNodes = (Select-Xml -Path $configFile -XPath '//Action').Node

do {
    $Answer = Read-Host -Prompt "Select required action '$($actionNodes.Name -join "', '")'"
} Until ($Answer -in ($actionNodes.Name))

$selectedNode = $actionNodes | Where-Object {$_.Name -eq $Answer}
Write-Host $selectedNode.Name

$selectedNode.DeploymentServer.Server | ForEach-Object {
    $ServerName = $_.Name
    Write-Host $ServerName
    
if($selectedNode.Name -ieq "deploy")
{
$ScriptCode  = $selectedNode.Deployscript1.Name
$ScriptCode2  = $selectedNode.Deployscript2.Name
}
Write-Host $ScriptCode
Write-Host $selectedNode.CommandPath

Invoke-Command -ComputerName $ServerName -ScriptBlock {
 $Configuration = $args[0]
 Set-Location $selectedNode.CommandPath

#Execute first command       
        & $ScriptCode

#Execute second command
        $ScriptCode2
    } -ArgumentList $SelectedAnswer
  }
}


$spAdminServiceName = "SPAdminV4"
$currentDir=(split-path $myinvocation.mycommand.path -parent)
$configFile = $currentDir
$configFile += "\DeployConfig.xml"
Execute-Commands $configFile

RunConfiguration

Write-Host -f White "Press Enter key to exit..."
Read-Host

I am getting the below 2 errors: Error 1: Cannot process argument because the value of argument "path" is null. Change the value of argument "path" to a non-null value.

Error 2: The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script block, or a CommandInfo object.

I am able to get correct path which is there in xml in the write host for the path. How to fix these 2 errors? Thanks

Updated Code 1: I am able to get the values from XML without any issues.

Invoke-Command -ComputerName $ServerName -ScriptBlock {
        $Configuration = $args[0]
  
#Navigate to location
        Set-Location $scriptPath.ToString()

#Execute first command

        & $ScriptCode

#Execute second command

        $ScriptCode1    
    } -ArgumentList $SelectedAnswer
1

1 Answers

0
votes

#1 - You dont appear to be defining $configFile?

$actionNodes = (Select-Xml -Path $configFile -XPath '//Action').Node

Try adding Write-Host "Config file is: $($configFile)"; at the start of RunConfiguration() function - is it the correct value? Is $configFile supposed to be passed as an argument or declared globally - your function currently does not accept any parameters?

#2 - The $ScriptCode variable is going to be an object, it needs to be a string. Check the type of a variable like this:

$ScriptCode.GetType()

When your calling Write-Host $ScriptCode what powershell is actually running is probably Write-Host $ScriptCode.ToString() - which returns just the correct text. When you pass that variable with the call operator & your passing the entire object not just the filename. You need to convert $ScriptCode to be a string first:

Try either (sorry, untested code):

& ([string] $ScriptCode)

or

& $ScriptCode.ToString()