6
\$\begingroup\$

Adapted from Tips for restricted source in Python


Just like , pushes one to exploit quirks and hidden features of the Powershell language. Now, We already have a place to collect all these for , those for remain transmitted by word of mouth or hidden deep within the Powershell documentation.

Let's collaborate on this thread to gather the tips for in Powershell!

Please only include 1 tip per answer.


What makes a good tip here?

There are a couple of criteria I think a good tip should have:

  1. It should be (somewhat) non obvious.

    Similar to the tips it should be something that someone who has golfed in python a bit and read the tips page would not immediately think of. For example "Replace a + b with a+b to avoid using spaces", is obvious to any golfer since it is already a way to make your code shorter and thus not a good tip.

  2. It should not be too specific.

    Since there are many different types of source restrictions, answers here should be at least somewhat applicable to multiple source restrictions, or one common source restriction. For example tips of the form How to X without using character(s) Y are generally useful since banned characters is a common source restriction. The thing your tip helps to do should also be somewhat general. For example tips of the form How to create numbers with X restriction are useful since many programs utilize numbers regardless of the challenge. Tips of the form How to implement Shor's algorithm with X restriction are basically just answers to a challenge you just invented and not very helpful to people solving other challenges.

\$\endgroup\$

3 Answers 3

8
\$\begingroup\$

Alternatives To Single And Double Quotes

{A}  #Normal Curly Braces; This makes a scriptblock, but the ToString prints the contents
‘B‘  # Left Single Quotation Mark              0x2018
’C’  # Right Single Quotation Mark             0x2019
‚D‚  # Single Low-9 Quotation Mark             0x201a
‛E‛  # Single High-Reversed-9 Quotation Mark   0x201b
“F“  # Left Double Quotation Mark              0x201c
”G”  # Right Double Quotation Mark             0x201d
„H„  # Double Low Quotation Mark               0x201E

PS C:\> {A}
A
PS C:\> ‘B‘
B
PS C:\> ’C’
C
PS C:\> ‚D‚
D
PS C:\> ‛E‛
E
PS C:\> “F“
F
PS C:\> ”G”
G
PS C:\> „H„
H

Yes, these work! But What's better? The quotes single quotes and double quotes act as their respective normal quotes, (') and ("), and {} behave like single quotes ('). Thus:

$x="A Variable"
‘$x‘
’$x’
‚$x‚
‛$x‛
“$x“
”$x”
„$x„
{$x}

outputs:

$x           # ‘$x‘
$x           # ’$x’
$x           # ‚$x‚
$x           # ‛$x‛
A Variable   # “$x“
A Variable   # ”$x”
A Variable   # „$x„
$x           # {$x}

As a final useful bit; you don't even have to match the starting and ending quotes, so long as they are of the same type (single/double). Meaning these:

‘$x‛
‚$x'
”$x“
„$x"

Are all perfectly valid, and output like so:

$x           # ‘$x‛
$x           # ‚$x'
A Variable   # ”$x“
A Variable   # „$x"

Alternative Dashes and Uncommon Whitespace

In addition to the additional quotes characters above, PowerShell recognizes some special dashes as equivalent to the hyphen (-):

5–4  # EN DASH          0x2013   [–]
3—2  # EM DASH          0x2014   [—]
1―1  # HORIZONTAL BAR   0x2015   [―]

Powershell also recognizes two other uncommon whitespace characters:

NoBreakSpace   0x00A0
NextLine       0x0085

These were found by @ZaelinGoodman's experiment here

If anything changes, or if you want to see the specifics of how these work, you can find the source code for this handling in the PowerShell Github

I made this community wiki, so this list can be freely updated.

\$\endgroup\$
3
  • \$\begingroup\$ In addition, you do not have to match the starting and ending quote character you chose, as long as they are the same "type" (single or double), so ‘Z' is valid. \$\endgroup\$
    – briantist
    Commented Mar 6, 2021 at 21:39
  • \$\begingroup\$ @briantist great catch! Added :) \$\endgroup\$ Commented Mar 6, 2021 at 22:13
  • \$\begingroup\$ Might be worth noting that ToString() on a scriptblock has dozens of corner cases where it doesn't work the same as an evaluated string, particularly with embedded variables, the reference and scope operators, and it can vary across different versions of Powershell. \$\endgroup\$
    – Bacon Bits
    Commented Oct 29, 2021 at 0:23
3
\$\begingroup\$

Using variables if $ is forbidden

Use the Get/Set-Variable:

Set-Variable myVar 5
Get-Variable myVar

And shorter with their aliases:

sv myVar 6
gv myVar

as Get-Variable returns a PSVariable object, use the -v for ValueOnly to get only the value

gv myVar -v

Note that it works for already defined variables such as $args in functions.

\$\endgroup\$
1
\$\begingroup\$

Printing numbers in Restricted source

You can use Boolean or hexadecimal numbers or print numbers in other way, in restricted source.


When performing arithmetic operations on Booleans, Powershell treats them as if they are the numbers 1 and 0. Basically, if you cast any undefended variable to [int], it will be considered as 0.

An example is:

PS C:\Users\Administrator> [int]$true
1
PS C:\Users\Administrator> [int]$false
0
PS C:\Users\Administrator> [int]$x #This variable is not defined
0

A shorter way is to add/subtract digits to the boolean/non-existent variable:

PS C:\Users\Administrator> $true+0
1
PS C:\Users\Administrator> $false+1
1
PS C:\Users\Administrator> $true+$true
2
PS C:\Users\Administrator> ($true+$true)*($true+$true)
4

Or just +$true, thanks to @mazzy

This especially comes useful if (most) digits are not allowed.


Hexadecimal numbers come up useful too, like if you aren't allowed to use 1-9 but have to print 100, then use 0xa*0xa (because 0xa=10)

PS C:\Users\Administrator> 0xa
10
PS C:\Users\Administrator> 0xa*0xa
100

Another tip is you can calculate a string's length (length of 18 xs):

PS C:\Users\Administrator> 'xxxxxxxxxxxxxxxxxx'.length
18
PS C:\Users\Administrator> 'xxxxxxxxxxxxxxxxxx'|% le*
18

use "$args" to cast the arguments to one value. use +"$args" if you need only one value, thanks to @mazzy

\$\endgroup\$
2
  • \$\begingroup\$ use the unary + to cast to [int]. for example, +$true. Don't use +0 and [int]. \$\endgroup\$
    – mazzy
    Commented Mar 7, 2021 at 4:36
  • \$\begingroup\$ use "$args" to cast the arguments to one value. use +"$args" if need it \$\endgroup\$
    – mazzy
    Commented Mar 7, 2021 at 4:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.