Error: Missing expression after unary operator '-'.At line:1 char:2+ -E

Onarklog
Mega Contributor

Error: Missing expression after unary operator '-'.At line:1 char:2+ -E <<<< xecutionPolicy ByPass -NonInteractive -WindowStyle Hidden -command & {mode con lines=1 cols=9999; Set-Variable -Name 'SNC_isWmi' -Value $true -Scope Global; function printValues{Process{foreach-object{if($_.Properties){$a=$_.Properties}else{$a=$_.PsObject.Properties}foreach($p in $a){$o=$p.Name+' : ';if ($p.Value -is [Array]){$o+=[string]::Join(',', $p.Value);}else{$o+=$p.Value;}$o;if($p.Value -is [System.Management.ManagementBaseObject] -or $p.Value -is [System.Management.ManagementBaseObject[]]){'_EXTENDED_START:';$p.Value|printValues;'_EXTENDED_END!';}}}}}gwmi -namespace root/MSCluster MSCluster_Cluster -EA SilentlyContinue|select __CLASS,Name|printValues|format-list;gwmi -namespace root/MSCluster MSCluster_ClusterToResource -EA SilentlyContinue|select __CLASS,GroupComponent,PartComponent|printValues|format-list;gwmi -namespace root/MSCluster MSCluster_ClusterToNode -EA SilentlyContinue|select __CLASS,Antecedent,Dependent|printValues|format-list;gwmi -namespace root/virtualization/v2 Msvm_ComputerSystem -EA SilentlyContinue|select __CLASS,Name|printValues|format-list;gwmi -namespace root/virtualization Msvm_ComputerSystem -EA SilentlyContinue|select __CLASS,Name|printValues|format-list;gwmi -namespace root/MSCluster MSCluster_Resource -EA SilentlyContinue|select __CLASS,PrivateProperties,Name,Type|printValues|format-list;gwmi -namespace root\cimv2 Win32_ComputerSystem -EA SilentlyContinue|select __CLASS,Domain,Name|printValues|format-list;gwmi -namespace root\cimv2 Win32_OperatingSystem -EA SilentlyContinue|select __CLASS,Caption,Version|printValues|format-list;gwmi -namespace root/MSCluster MSCluster_Node -EA SilentlyContinue|select __CLASS,Name|printValues|format-list;'---SNC-SEPERATOR---REGISTRY-SECTION---';Get-ItemProperty -Path 'HKLM:/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters' -EA SilentlyContinue|select PSPath,Domain,Hostname|format-list;}HRESULT: [-2147024894]

 

 

MID server Powershell version is 4.0

 

 

Here is the script Service Now is running:

 

  1. function getConfigurableParm {
  2. param([string]$variable, [string]$defaultValue)
  3. $value = [Environment]::GetEnvironmentVariable($variable)
  4. if (-not $value) {
  5. $value = $defaultValue;
  6. }
  7. return $value;
  8. }
  9. <# Benjamin Phan:
  10. This function should probably not be called outside of executeRemote, since this function depends on variables being set
  11. by executeRemote. We might want to refactor executeRemote so that this part is placed inline rather than in this function.
  12. I originally made it this way because it seemed easier to read, but really it should not be a function in case someone
  13. comes across it and tries to use it standalone.
  14. #>
  15. function launchWMI {
  16. param([string]$computer, [System.Management.Automation.PSCredential]$cred, [string]$sourceScript, [string]$scriptBlock, [switch]$copyScriptToTarget)
  17. $context = startImpersonation $cred
  18. $cmdLongline = "mode con lines=1 cols=9999";
  19. $cmdPowerShellPrefix = "powershell -ExecutionPolicy ByPass -NonInteractive -WindowStyle Hidden";
  20. # set some useful variables
  21. $varString = "Set-Variable -Name 'SNC_isWmi' -Value `$true -Scope Global; "
  22. # check if we have any variables we need to send to the remote session
  23. $remoteVarsVariable = Get-ChildItem -Path Env:SNCExecuteRemoteVars 2> $null
  24. if ($?) {
  25. $paramNamesString = $remoteVarsVariable.Value
  26. $vars = ($paramNamesString -split ",")
  27. # build up command containing variables and values to pass to remote session
  28. Foreach ($var in $vars) {
  29. $varObj = Get-Variable -Name $var
  30. $varName = $varObj.Name
  31. $varVal = $varObj.Value
  32. # only need to escape single quotes, double quotes are passed properly without escaping
  33. $escapedVarVal = $varVal -replace "'","''"
  34. $varString += "Set-Variable -Name '$varName' -Value '$escapedVarVal' -Scope Global; "
  35. }
  36. }
  37. # If we got a sourceScript as a file path and we should not copy the script to the target, run the script as script block.
  38. if ($sourceScript -and -not $copyScriptToTarget) {
  39. $scriptBlock = (Get-Content -path $sourceScript)
  40. }
  41. if ($scriptBlock){
  42. # If we get a string as a script block, attach the the command to make sure that the windows is large enough for long line and pass is as the powerlshell command
  43. $varCommand = "& {$cmdLongline; $varString $scriptBlock}";
  44. # escape the command for cmd
  45. # for sequences of backslashes followed by double quote, double the number of quotes
  46. # also convert any " to \""
  47. $escapedCommand = $varCommand -replace '(\\*)"', '$1$1\""'
  48. $command = "$cmdPowerShellPrefix -command `"$escapedCommand`""
  49. }
  50. else {
  51. # Create directories as needed and copy script to directory
  52. $pathExists = Test-Path -Path $remoteHomeDir
  53. if (-not $?) {
  54. throw "Failed to test the path $remoteHomeDir"
  55. }
  56. if (-not $pathExists) {
  57. New-Item -ItemType directory -Path $remoteHomeDir -Force > $null
  58. if (-not $?) {
  59. throw "Failed to create directory $remoteHomeDir"
  60. }
  61. }
  62. Copy-Item -Path $sourceScript -Destination $remoteScriptPath -Force -Recurse
  63. if (-not $?) {
  64. throw "Failed to copy script $sourceScript to target $remoteScriptPath"
  65. }
  66. # create a script on the target that contains the commands to set powershell params
  67. $paramFileGuid = [System.Guid]::NewGuid()
  68. $targetParamFileName = "executeRemote_params_$paramFileGuid.ps1"
  69. $remoteParamScript = "$remoteHomeDir\$targetParamFileName"
  70. $localParamScript = "$localHomeDir\$targetParamFileName"
  71. # add the home directory and script path to the parameters that are passed to the remote powershell process
  72. $varString += "Set-Variable -Name 'SNC_remoteScriptDirectory' -Value '$localHomeDir' -Scope Global; "
  73. $varString += "Set-Variable -Name 'SNC_remoteScriptPath' -Value '$localScriptPath' -Scope Global; "
  74. New-Item -ItemType "file" -Path $remoteParamScript -Force > $null
  75. Set-Content -Value $varString -Path $remoteParamScript -Force -Encoding UTF8
  76. $hasParams = $true
  77. $runParamsScript = "try { & $localParamScript; } catch {}"
  78. # Potential security issue: passing parameters to target through plain text
  79. $varCommand = "& {$cmdLongline; $runParamsScript & $localScriptPath $localParamScript}"
  80. $command = "$cmdPowerShellPrefix -command `"$varCommand`""
  81. }
  82. # Run script remotely
  83. try {
  84. # call launchProcess with -UTF8 so that unicode characters are brought back and put into the payload properly
  85. if ($launchProcessWaitTime) {
  86. launchProcess -computer $computer -cred $cred -command $command -UTF8 -secondsToWait $launchProcessWaitTime
  87. } else {
  88. launchProcess -computer $computer -cred $cred -command $command -UTF8
  89. }
  90. } catch [System.IO.FileNotFoundException] {
  91. throw;
  92. } catch {
  93. write-error $_.Exception.Message
  94. } finally {
  95. if (-not $scriptBlock){
  96. Remove-Item -Path $remoteScriptPath -Force
  97. if ($hasParams) {
  98. Remove-Item -Path $remoteParamScript -Force
  99. }
  100. }
  101. }
  102. endImpersonation $context
  103. }
  104. function executeRemote {
  105. Param([string]$computer, [string][Parameter(ParameterSetName='filePath')]$filePath, [string][Parameter(ParameterSetName='scriptBlock')]$scriptBlock, [boolean] $wmi, [System.Management.Automation.PSCredential]$cred, [switch]$copyScriptToTarget, [int]$launchProcessWaitTime)
  106. $targetBaseDir = getConfigurableParm -variable "SNC_base_dir" -defaultvalue "admin$\temp"
  107. $instanceName = getConfigurableParm -variable "SNC_instance" -defaultvalue "unregistered"
  108. $targetFileGuid = [System.Guid]::NewGuid()
  109. $targetFileName = "psscript_executeRemote_$targetFileGuid.ps1"
  110. $homeDir = "$targetBaseDir\$instanceName"
  111. $localHomeDir = "\\127.0.0.1\$homeDir"
  112. $localScriptPath = "$localHomeDir\$targetFileName"
  113. $remoteHomeDir = "\\$computer\$homeDir"
  114. $remoteScriptPath = "$remoteHomeDir\$targetFileName"
  115. if ($wmi) {
  116. launchWMI -computer $computer -cred $cred -sourceScript $filePath -scriptBlock $scriptBlock -copyScriptToTarget:$copyScriptToTarget;
  117. } else {
  118. $remotePs = CreatePSSessionWithComputerName -host $computer -credential $cred
  119. if ($remotePs) {
  120. # pass powershell_param_ variables to the remote session
  121. if ($SNC_REMOTE_VARIABLES) {
  122. $varNames = $SNC_REMOTE_VARIABLES -split ","
  123. Foreach ($varName in $varNames) {
  124. $value = (Get-Variable $varName).Value
  125. # only need to escape single quotes, double quotes are passed properly without escaping
  126. $escapedValue = $value -replace "'","''"
  127. $sbString = "Set-Variable -Name '$varName' -Value '$escapedValue'"
  128. $paramsSb = [scriptblock]::Create($sbString)
  129. Invoke-Command -Session $remotePs -ScriptBlock $paramsSb
  130. }
  131. }
  132. if ($copyScriptToTarget) {
  133. # copy the script to the target
  134. SendFileExecuteRemote -Path $filePath -Destination $localHomeDir -Name $targetFileName -Session $remotePs > $null
  135. # pass the directory of the script on target to the remote session
  136. $sbString = "Set-Variable -Name 'SNC_remoteScriptDirectory' -Value '$localHomeDir'"
  137. $paramsSb = [scriptblock]::Create($sbString)
  138. Invoke-Command -Session $remotePs -ScriptBlock $paramsSb
  139. # pass the path of the script on target to the remote session
  140. $sbString = "Set-Variable -Name 'SNC_remoteScriptPath' -Value '$localScriptPath'"
  141. $paramsSb = [scriptblock]::Create($sbString)
  142. Invoke-Command -Session $remotePs -ScriptBlock $paramsSb
  143. # Tell the remote that we're not using WMI
  144. $sbString = "Set-Variable -Name 'SNC_isWmi' -Value `$false"
  145. $paramsSb = [scriptblock]::Create($sbString)
  146. Invoke-Command -Session $remotePs -ScriptBlock $paramsSb
  147. # execute the script on the target
  148. $executeScriptSb = [ScriptBlock]::Create("Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass; & `"$localScriptPath`"")
  149. $output = Invoke-Command -Session $remotePs -ScriptBlock $executeScriptSb -ErrorAction Continue
  150. #remove the script on the target
  151. $removeFileSb = [ScriptBlock]::Create("Remove-Item $localScriptPath -Force")
  152. Invoke-Command -Session $remotePs -ScriptBlock $removeFileSb > $null
  153. } else {
  154. # execute the script on the target
  155. $output = Invoke-Command -Session $remotePs -FilePath $filePath -ErrorAction Continue
  156. }
  157. foreach ($out in $output) {
  158. # must use [Console]::WriteLine because [Console]::OutputEncoding is properly set to UTF8
  159. # Write-Host and Write-Output do not correctly pass unicode characters back to MID Java code
  160. [Console]::WriteLine($out)
  161. }
  162. } else {
  163. Write-Error "Failed to create remote Powershell Session"
  164. }
  165. }
  166. }
  167. function SendFileExecuteRemote
  168. {
  169. <#
  170. Author: Benjamin Phan
  171. 10/12/18
  172. Ripped from LaunchProc.psm1 with modifications.
  173. This Send-File takes in a Destination directory and a Name, which allows us to change the resulting file's name.
  174. The original Send-File sets the resulting file's name to be the same as the source file.
  175. Another difference is that this function does not use using:$variables, since this functionality does not seem
  176. to be supported in Powershell 2.0.
  177. We need this function inside this module because LaunchProc.psm1 is not imported into the Powershell session
  178. when we are on the WinRM code path.
  179. #>
  180. [CmdletBinding()]
  181. param
  182. (
  183. [string[]]$Path,[string]$Destination, [string]$Name, [System.Management.Automation.Runspaces.PSSession]$Session
  184. )
  185. process
  186. {
  187. foreach ($p in $Path)
  188. {
  189. try
  190. {
  191. if ($p.StartsWith('\\'))
  192. {
  193. Write-Verbose -Message "[$($p)] is a UNC path. Copying locally first"
  194. Copy-Item -Path $p -Destination ([environment]::GetEnvironmentVariable('TEMP', 'Machine'))
  195. $p = "$([environment]::GetEnvironmentVariable('TEMP', 'Machine'))\$($p | Split-Path -Leaf)"
  196. }
  197. if (Test-Path -Path $p -PathType Container)
  198. {
  199. Write-Log -Source $MyInvocation.MyCommand -Message "[$($p)] is a folder. Sending all files"
  200. $files = Get-ChildItem -Path $p -File -Recurse
  201. $sendFileParamColl = @()
  202. foreach ($file in $Files)
  203. {
  204. $sendParams = @{
  205. 'Session' = $Session
  206. 'Path' = $file.FullName
  207. }
  208. if ($file.DirectoryName -ne $p) ## It's a subdirectory
  209. {
  210. $subdirpath = $file.DirectoryName.Replace("$p\", '')
  211. $sendParams.Destination = "$Destination\$subDirPath"
  212. }
  213. else
  214. {
  215. $sendParams.Destination = $Destination
  216. }
  217. $sendFileParamColl += $sendParams
  218. }
  219. foreach ($paramBlock in $sendFileParamColl)
  220. {
  221. Send-File @paramBlock
  222. }
  223. }
  224. else
  225. {
  226. Write-Verbose -Message "Starting WinRM copy of [$($p)] to [$($Destination)]"
  227. # Get the source file, and then get its contents
  228. $sourceBytes = [System.IO.File]::ReadAllBytes($p);
  229. $streamChunks = @();
  230. # Now break it into chunks to stream.
  231. $streamSize = 1MB;
  232. for ($position = 0; $position -lt $sourceBytes.Length; $position += $streamSize)
  233. {
  234. $remaining = $sourceBytes.Length - $position
  235. $remaining = [Math]::Min($remaining, $streamSize)
  236. $nextChunk = New-Object byte[] $remaining
  237. [Array]::Copy($sourcebytes, $position, $nextChunk, 0, $remaining)
  238. $streamChunks +=, $nextChunk
  239. }
  240. $remoteScript = {
  241. param($dest, $fname, $len)
  242. if (-not (Test-Path -Path $dest -PathType Container))
  243. {
  244. $null = New-Item -Path $dest -Type Directory -Force
  245. }
  246. $fileDest = "$dest\$fname"
  247. ## Create a new array to hold the file content
  248. $destBytes = New-Object byte[] $len
  249. $position = 0
  250. ## Go through the input, and fill in the new array of file content
  251. foreach ($chunk in $input)
  252. {
  253. [GC]::Collect()
  254. [Array]::Copy($chunk, 0, $destBytes, $position, $chunk.Length)
  255. $position += $chunk.Length
  256. }
  257. [IO.File]::WriteAllBytes($fileDest, $destBytes)
  258. Get-Item $fileDest
  259. [GC]::Collect()
  260. }
  261. # Stream the chunks into the remote script.
  262. $Length = $sourceBytes.Length
  263. $streamChunks | Invoke-Command -Session $Session -ScriptBlock $remoteScript -ArgumentList $Destination,$Name,$Length
  264. Write-Verbose -Message "WinRM copy of [$($p)] to [$($Destination)] complete"
  265. }
  266. }
  267. catch
  268. {
  269. Write-Error $_.Exception.Message
  270. }
  271. }
  272. }
  273. }
2 REPLIES 2

robertgeen
Tera Guru

What version are you? If it's the lower versions of Madrid before I think patch 4 it could be related to the WMI change. There was a HI KB for it but they seem to have made it private:

https://hi.service-now.com/kb_view.do?sys_kb_id=f1913a27dbd8c414d82ffb24399619f9&sysparm_rank=1&sysp...

But there were numerous issues due to a change to powershell 2.0. If you aren't on that version that I strongly recommend you open up a HI ticket as it's going to be very difficult to figure that out. 

New York. We haven't seen this error before upgrade...MID server is running 4.0 Powershell