Need to fit your PowerShell oneliner in a Twitter message? Oh, noes!!! Too many characters! Let’s shorten that one-liner with some useful tricks.
Darren Kitchen has a great Youtube channel about pen-testing for IT pros. He frequently makes use of the Windows Run box to execute PowerShell oneliners as payload to execute cool stuff.
In one of his latest videos, he shows how we can use a one-liner to set the Windows wallpaper to make use of a happy bunny. 252 characters just fits in a Run box, but we can make that even shorter!
cmd /C "start /MIN powershell iwr -Uri http://h4k.cc/b.jpg -OutFile c:\windows\temp\b.jpg;sp 'HKCU:Control Panel\Desktop' WallPaper 'c:\windows\temp\b.jpg';$a=1;do{RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True;sleep 1}while($a++-le59)"
1. Make use of aliases
I’m a big fan of aliases! Previously, I searched my interactive shell for new unknown aliases with some kind of success. However, I know Visual Studio is not so kind for my use of aliases.
‘Sleep’ is an alias of ‘Start-Sleep’.
PSScriptAnalyzer(PSAvoidUsingCmdletAliases)can introduce possible problems and make scripts hard to maintain. Please consider changing Alias to its full content. alias
Anyway, aliases can really save
Example
Invoke-WebRequest contains a lot of characters. And, we can replace this with the much shorter alias Iwr. Let’s check how much characters we saved.
"Invoke-WebRequest".Length
17
"Iwr".Length
3
"Invoke-WebRequest".Length - "Iwr".Length
14
Nice, we saved 14 characters already!
2. Remove or shorten long parameters
Positional parameters
Each function or method in PowerShell can make use of several parameters. Some of these parameters can have a position. This means you can omit this parameter switch and PowerShell will know what you mean by using the position of the parameter.
You can always check the documentation for positional parameters. Microsoft Docs is
Example
Invoke-WebRequest -URI https://www.google.be
Microsoft Docs documents all parameters for Invoke-WebRequest. -URI is defined as a parameter with position 0. So if we can just omit the -URI part.
Invoke-WebRequest https://www.google.be
Ambiguous parameters
Sometimes, cmdlets contain lots of parameters. These parameters need to be unique to avoid ambiguity. But if just use the beginning part of the parameter name, we can omit the rest of the name.
When 2 parameters begin with the same letter, the second letter can make the string
unambiguous again.
Example
Invoke-WebRequest https://www.google.be -Credential "Domain01\User01"
Invoke-WebRequest contains multiple parameters beginning with “C”. So we can use the second character to avoid confusion.
- Certificate
- CertificateT
humbprint - Co
ntentType - Cr
edential
Invoke-WebRequest https://www.google.be -Cr "Domain01\User01"
Parameter aliases
Parameters can be aliased too! Oooooh, I do love PowerShell. You can check out documentation of parameter aliases here.
Example
Invoke-WebRequest https://www.google.be -CustomMethod "GET"
The -CustomMethod parameter has a defined alias of -CM (PowerShell 6.0.0).
Invoke-WebRequest https://www.google.be -CM "GET"
3. Use variables or automatic variables
Sometimes, our one-liner contains duplicate information. For example, we could enter the same path to our folder twice. What a waste of characters!
Create a variable for later re-use
Let’s go with a path as
iwr -Uri http://h4k.cc/b.jpg -OutFile c:\windows\temp\b.jpg;sp 'HKCU:Control Panel\Desktop' WallPaper 'c:\windows\temp\b.jpg'
As you notice, the path is used twice. We would create a variable $P containing the long string. This way, each time we use $P, we save a lot of characters in our one-liner.
$P = "c:\windows\temp\b.jpg"; iwr -Uri http://h4k.cc/b.jpg -OutFile $P;sp 'HKCU:Control Panel\Desktop' WallPaper $P
Automatic variables
Automatic variables are variables created and maintained by PowerShell. You can find a list of automatic variables on SS64.
$Home | Contains the full path of the user’s home directory. ReadOnly, AllScope This variable is the equivalent of the %HomeDrive%%HomePath% environment variables, typically C:\Users\<user> |
$Profile | Contains the full path of the Windows PowerShell profile for the current user and the current host application. You can use this variable to represent the profile in commands. For example, you can use it in a command to determine whether a profile has been created: test-path $profile Or, you can use it in a command to create a profile: new-item -type file -path $pshome -force You can also use it in a command to open the profile in Notepad: notepad $profile |
$PSCommandPath | Contains the full path and file name of the script that is being run. This variable is valid in all scripts. |
$Pwd | Contains a path object that represents the full path of the current directory. |
$PsHome | Contains the full path of the installation directory for Windows PowerShell, Constant, AllScope Typically, %windir%\System32\WindowsPowerShell\v1.0 You can use this variable in the paths of Windows PowerShell files. For example, the following command searches the conceptual Help topics for the word “variable”: select-string -pattern variable -path $pshome\*.txt |
$PSScriptRoot | Contains the directory from which the script module is being executed. This variable allows scripts to use the module path to access other resources. In PowerShell 3.0+ this is available everywhere, not just in modules. |
Of course, these are just a couple of tricks we can use. If you have some more tips, please leave a comment! Maybe we can write a follow-up article 🙂