Deploy PowerShell as Clickable Icons (Part 1)

by Oct 27, 2020

You can use .lnk files to deploy small PowerShell solutions to end users. Here’s how:

Take below code, and replace the payload code inside $code with whatever PowerShell code you’d like your clickable icon to execute. Just make sure the code is less than 4096 characters in total. Then run the script.

$code = {
   # place your code here (must be less than 4096 characters)
   # (this example generates a battery report on notebooks
   #  and opens it in your default browser)
   $r = "$env:temp\report.html"
   powercfg /batteryreport /duration 14 /output $r
   Invoke-Item -Path $r
   Start-Sleep -Seconds 2
   Remove-Item -Path $r
}

# turn code into a one-liner, remove comments, escape double-quotes
# NOTE: this is a very simplistic conversion. Does not support block comments
#  or quoted double quotes or any edgy stuff
#  USE with simple staight-forward code only
$oneliner = $code.ToString().Trim().Replace('"','\"').
              Replace([Char[]]10,'').Split([Char[]]13).
              Trim().Where{!$_.StartsWith('#')} -join ''

# create path to a link file. It is always placed on your desktop
# and named "clickme.lnk"
$desktop = [Environment]::GetFolderPath('Desktop')
$linkpath = Join-Path -Path $desktop -ChildPath 'ClickMe.lnk'

# create a shortcut file
$com = New-Object -ComObject WScript.Shell
$shortcut = $com.CreateShortcut($linkpath)
# minimize window so PowerShell won't pop up
$shortcut.WindowStyle = 7
# use a different icon. Adjust icon index if you want
$shortcut.IconLocation = 'shell32.dll,8'
# run PowerShell
$shortcut.TargetPath = "powershell.exe"
# submit code as an argument
$shortcut.Arguments = "-noprofile $oneliner"

# save and create the shortcut file
$shortcut.Save()

The result is an icon on your desktop named “clickme”, and when you double-click this icon, the embedded PowerShell code runs. If you did not change the payload script in the example above, it will generate a battery report and display it in your default browser.

Since the payload code is embedded in the icon file, you can happily pass it to others or deploy it.

There are a few things to consider when you adjust the embedded payload script in $code:

  1. Code must be less than 4096 characters in total
  2. Do not use block comments, or best remove all comment lines (to reduce payload size)
  3. Do not use quoted double quotes as double quotes must be escaped, and the script does not use a very clever algorithm. It simply escapes all double quotes it finds.

Twitter This Tip! ReTweet this Tip!