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’. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content.

PSScriptAnalyzer(PSAvoidUsingCmdletAliases)

Anyway, aliases can really save lot’s of characters.

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 great source of information.

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
  • CertificateThumbprint
  • ContentType
  • Credential
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 example.

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.

$HomeContains 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>
$ProfileContains 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
$PSCommandPathContains the full path and file name of the script that is being run. This variable is valid in all scripts.
$PwdContains a path object that represents the full path of the current directory.
$PsHomeContains 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 🙂


3 Comments

postnaote · 12/01/2019 at 20:06

It’s a best practice to never, ever do this in production or shared or community scripts. It makes scripts very hard to read, understand, troubleshoot and maintain, they are also not consistent and do not exist in all PowerShell versions on different OS versions.

You can do this to in your scripts as you develop them to decrease typing, but you must absolutely expand all the aliases before release to anyone.

This sort of thing is great and optimal for quick consolehost or code interactive stuff. So, definitely good thing to learn for that quick keyboard stuff.

postanote · 12/01/2019 at 20:12

Also, this …

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)”

… is not a one-liner.

It’s a bunch of separate commands/code on one line. That semi colon in PowerShell specifically means, the code line that follows is a completely separate command than the one that proceeds it.

PowerShell, One-liners, are single command / code block / scriptblock or pipelined (passing the results or some part of it) to the next command / code block / scriptblock..

    yvez · 12/01/2019 at 20:25

    Cool! Thanks for posting, appreciate it.

Leave a Reply

Your email address will not be published. Required fields are marked *