Home > other >  PowerShell passing string values to parameters
PowerShell passing string values to parameters

Time:11-29

Context is PowerShell, Register-ScheduledTask. I have a difficulty when extracting a value from XML, then passing it to a parameter as a string. The cmdlet allows me to specify an exported XML file as the definition of the scheduled task. In principle, my command is "create a new scheduled task from this XML". The cmdlet provides explicit parameters for TaskName, TaskPath and User, but I would like to obtain these directly from the XML. I can successfully use the XML notation to obtain the URI from the XML. I can successfully split this into a $TaskName and a $TaskPath. I can also obtain the Principal Userid from the XML. But when I pass this to the cmdlet as $User I receive an error "No mappings between account names and security IDs was done". The strange thing is that the $TaskName contains spaces, but is accepted by the cmdlet. The $User may or may not have spaces, but is not accepted. Whereas if I simply create $User as a normal quoted string variable it is accepted. Relevant snippets:

[xml]$taskXml = Get-Content -Path $XmlPath
$taskUser = $($task.xml.Task.Principals.Principal.UserId)
[string]$User = $(taskUser | Out-String)
Register-ScheduledTask -Xml (Get-Content -Path $XmlPath -Raw) -User $User

If I simply specify the $User = "S-1-5-18", for example, the cmdlet works. It might be a simple problem of passing strings that need to be quoted. But $TaskName (derived from the XML) also has spaces, and that passes fine to the parameter -TaskName. What is going on?

CodePudding user response:

Do not use Out-String, because it invariably adds a trailing newline to its output.

Type-constraining your $User variable as [string] implicitly performs stringification (albeit via .ToString(), not via PowerShell's for-display-formatting system, the way Out-String does for non-primitive .NET types).

Additionally, passing a value to Register-ScheduledTask's -User parameter also implicitly stringifies via .ToString(), given that it is [string]-typed:

Therefore, the following is presumably enough:

[xml] $taskXml = Get-Content -Raw $XmlPath
$taskUser = $taskXml.Task.Principals.Principal.UserId
Register-ScheduledTask -Xml (Get-Content -Path $XmlPath -Raw) -User $taskUser

Note that I've corrected what I presume is a typo: $task.xml. -> $taskXml.

As an aside:

  • For robustness [xml] (Get-Content ...) should be avoided, because Get-Content may misinterpret the character encoding of XML files. Use the [xml] type's .Load() method instead; e.g.: ($xmlDoc = [xml]::new()).Load((Convert-Path ./file.xml)) - see the bottom section of this answer for details.
  • Related