Search code examples
xmlpowershelljenkinsjenkins-plugins

How do I execute ps script in XML


I have one PS script that need to be execute/invoke via XML. getting error like

$sessions = Get-RDUserSession foreach($session in $sessions){Invoke- ...

Unexpected token 'in' in expression or statement. At line:1 char:78 $sessions = Get-RDUserSession foreach($session in $sessions){Invoke- ...
Missing closing ')' in expression. At line:1 char:109

config.xml

<Action name="KillAllUsers" Type="Powershell" Executor='$sessions = Get-RDUserSession
foreach ( $session in $sessions ) 
{ Invoke-RDUserLogoff -HostServer $session.HostServer -UnifiedSessionID $session.UnifiedSessionId -Force }'></Action>

Solution

  • Literal[1] newlines (line breaks) in XML attributes of XML text are seemingly not preserved when XML text is parsed into a DOM (Document Object Model); they are replaced with spaces.

    Therefore, whatever code you put in your Executor attribute ends up as a single line, which is why you must ;, PowerShell's statement separator, to separate your statements; note the ; after Get-RDUserSession and note that the line breaks are purely for readability here:

    <Action name="KillAllUsers" Type="Powershell" Executor='
    $sessions = Get-RDUserSession;
    foreach ( $session in $sessions ) { 
      Invoke-RDUserLogoff -HostServer $session.HostServer -UnifiedSessionID $session.UnifiedSessionId -Force
    }
    '></Action>
    

    As for the error you saw:

    Due to your code being placed all on a single line without statement separators, the foreach statement syntactically became an argument to the Get-RDUserSession command, which caused a syntax error; a simple way to provoke the error is:

    # -> ERROR: "Unexpected token 'in' in expression or statement."
    Get-Date foreach ($i in 1..2) { $i }
    

    [1] By contrast, escaped line breaks (&#xA; for LF-only newlines, &#xD;&#xA; for CRLF newlines) are preserved: they are converted to literal newlines in memory (in the DOM), and reconverted to their escaped form during serialization, i.e. when converting the in-memory DOM to a string or saving it to a file.