Reputation: 25
I'm trying to convert the below command to a single line, but to no avail. I've tried putting more apsas, braces, square brackets, but nothing.
$PBIFolder = Get-ChildItem -Path "$env:AllUsersProfile\Package Cache\" -Filter "PBIDesktopSetup_x64.exe" -Recurse
$PBISetup = $env:SystemDrive+$PBIFolder.PSParentPath.Split(':')[3]+"\PBIDesktopSetup_x64.exe"
Start-Process $PBISetup '/uninstall /quiet' -Wait
I tried this way but without success
powershell.exe -noprofile -noninteractive -command ($PBIFolder = Get-ChildItem -Path "$env:AllUsersProfile\Package Cache\" -Filter "PBIDesktopSetup_x64.exe" -Recurse; $PBISetup = $env:SystemDrive+$PBIFolder.PSParentPath.Split(':')[3]+"\PBIDesktopSetup_x64.exe"; Start-Process $PBISetup -Parameters '/uninstall /quiet' -Wait)
Upvotes: 1
Views: 1788
Reputation: 13
Try:
powershell.exe '-noprofile -noninteractive -command &($PBIFolder = Get-ChildItem -Path "$env:AllUsersProfile\Package Cache\" -Filter "PBIDesktopSetup_x64.exe" -Recurse; $PBISetup = $env:SystemDrive+$PBIFolder.PSParentPath.Split(':')[3]+"\PBIDesktopSetup_x64.exe"; Start-Process $PBISetup -Parameters '/uninstall /quiet' -Wait)'
Upvotes: 0
Reputation: 10323
Here's an alternate approach I like to use when I have longer script that need to be executed inline without relying on an external script file.
Instead of trying to put everything on a single line, I use the -EncodedCommand
argument of Powershell.exe
. That way, there is never any issue since the encoded command is a Base 64 string representation of the script.
To get the proper call, you would need to convert the script into a Base64 string first. See how I wrapped your script.
[System.Convert]::ToBase64String(
[System.Text.Encoding]::Unicode.GetBytes({
$PBIFolder = Get-ChildItem -Path "$env:AllUsersProfile\Package Cache\" -Filter "PBIDesktopSetup_x64.exe" -Recurse
$PBISetup = $env:SystemDrive + $PBIFolder.PSParentPath.Split(':')[3] + "\PBIDesktopSetup_x64.exe"
Start-Process $PBISetup '/uninstall /quiet' -Wait
}))
The string we get from that is :
"CgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAkAFAAQgBJAEYAbwBsAGQAZQByACAAPQAgAEcAZQB0AC0AQwBoAGkAbABkAEkAdABlAG0AIAAtAFAAYQB0AGgAIAAiACQAZQBuAHYAOgBBAGwAbABVAHMAZQByAHMAUAByAG8AZgBpAGwAZQBcAFAAYQBjAGsAYQBnAGUAIABDAGEAYwBoAGUAXAAiACAALQBGAGkAbAB0AGUAcgAgACIAUABCAEkARABlAHMAawB0AG8AcABTAGUAdAB1AHAAXwB4ADYANAAuAGUAeABlACIAIAAtAFIAZQBjAHUAcgBzAGUACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAkAFAAQgBJAFMAZQB0AHUAcAAgAD0AIAAkAGUAbgB2ADoAUwB5AHMAdABlAG0ARAByAGkAdgBlACAAKwAgACQAUABCAEkARgBvAGwAZABlAHIALgBQAFMAUABhAHIAZQBuAHQAUABhAHQAaAAuAFMAcABsAGkAdAAoACcAOgAnACkAWwAzAF0AIAArACAAIgBcAFAAQgBJAEQAZQBzAGsAdABvAHAAUwBlAHQAdQBwAF8AeAA2ADQALgBlAHgAZQAiAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgACQAUABCAEkAUwBlAHQAdQBwACAAJwAvAHUAbgBpAG4AcwB0AGEAbABsACAALwBxAHUAaQBlAHQAJwAgAC0AVwBhAGkAdAAKAA=="
From there, you can make your Powershell call but instead of the -Command
argument, you use -EncodedCommand
.
powershell.exe -noprofile -noninteractive -EncodedCommand "CgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAkAFAAQgBJAEYAbwBsAGQAZQByACAAPQAgAEcAZQB0AC0AQwBoAGkAbABkAEkAdABlAG0AIAAtAFAAYQB0AGgAIAAiACQAZQBuAHYAOgBBAGwAbABVAHMAZQByAHMAUAByAG8AZgBpAGwAZQBcAFAAYQBjAGsAYQBnAGUAIABDAGEAYwBoAGUAXAAiACAALQBGAGkAbAB0AGUAcgAgACIAUABCAEkARABlAHMAawB0AG8AcABTAGUAdAB1AHAAXwB4ADYANAAuAGUAeABlACIAIAAtAFIAZQBjAHUAcgBzAGUACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAkAFAAQgBJAFMAZQB0AHUAcAAgAD0AIAAkAGUAbgB2ADoAUwB5AHMAdABlAG0ARAByAGkAdgBlACAAKwAgACQAUABCAEkARgBvAGwAZABlAHIALgBQAFMAUABhAHIAZQBuAHQAUABhAHQAaAAuAFMAcABsAGkAdAAoACcAOgAnACkAWwAzAF0AIAArACAAIgBcAFAAQgBJAEQAZQBzAGsAdABvAHAAUwBlAHQAdQBwAF8AeAA2ADQALgBlAHgAZQAiAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgACQAUABCAEkAUwBlAHQAdQBwACAAJwAvAHUAbgBpAG4AcwB0AGEAbABsACAALwBxAHUAaQBlAHQAJwAgAC0AVwBhAGkAdAAKAA=="
Should you need to decode the command to edit it, you can do something like this (see below), then re-encode the modified script afterward and update your encoded command.
# $EncodedCommand need to be set to your base 64 string to be decoded.
$EncodedCommand = 'SABlAGwAbABvACAAVwBvAHIAbABkAA==' # Encoded "Hello World"
[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($EncodedCommand))
The advantage is that you don't loose readability since your editable version remains on multiple lines. You also avoid any parsing issues for more complex script.
Upvotes: 4
Reputation: 174485
Use the -EncodedCommand
switch - it accepts a command/script as a base64 string, ideal for storing a single script as a command line argument:
powershell.exe -EncodedCommand <base64-encoded-script>
To encode a script:
# assign code to a variable
# in real life you would read this from the file with `Get-Content path\to\script.ps1 -Raw`
$rawCode = @'
$PBIFolder = Get-ChildItem -Path "$env:AllUsersProfile\Package Cache\" -Filter "PBIDesktopSetup_x64.exe" -Recurse
$PBISetup = $env:SystemDrive+$PBIFolder.PSParentPath.Split(':')[3]+"\PBIDesktopSetup_x64.exe"
Start-Process $PBISetup '/uninstall /quiet' -Wait
'@
# UTF16LE-encode the script
$utf16EncodedScript = [System.Text.Encoding]::Unicode.GetBytes($rawCode)
# Base64-encode the resulting byte string
[System.Convert]::ToBase64String($utf16EncodedScript)
The resulting command line then becomes:
powershell.exe -EncodedCommand JABQAEIASQBGAG8AbABkAGUAcgAgAD0AIABHAGUAdAAtAEMAaABpAGwAZABJAHQAZQBtACAALQBQAGEAdABoACAAIgAkAGUAbgB2ADoAQQBsAGwAVQBzAGUAcgBzAFAAcgBvAGYAaQBsAGUAXABQAGEAYwBrAGEAZwBlACAAQwBhAGMAaABlAFwAIgAgAC0ARgBpAGwAdABlAHIAIAAiAFAAQgBJAEQAZQBzAGsAdABvAHAAUwBlAHQAdQBwAF8AeAA2ADQALgBlAHgAZQAiACAALQBSAGUAYwB1AHIAcwBlAAoAJABQAEIASQBTAGUAdAB1AHAAIAA9ACAAJABlAG4AdgA6AFMAeQBzAHQAZQBtAEQAcgBpAHYAZQArACQAUABCAEkARgBvAGwAZABlAHIALgBQAFMAUABhAHIAZQBuAHQAUABhAHQAaAAuAFMAcABsAGkAdAAoACcAOgAnACkAWwAzAF0AKwAiAFwAUABCAEkARABlAHMAawB0AG8AcABTAGUAdAB1AHAAXwB4ADYANAAuAGUAeABlACIACgBTAHQAYQByAHQALQBQAHIAbwBjAGUAcwBzACAAJABQAEIASQBTAGUAdAB1AHAAIAAnAC8AdQBuAGkAbgBzAHQAYQBsAGwAIAAvAHEAdQBpAGUAdAAnACAALQBXAGEAaQB0AA==
Upvotes: 2