SEC504: Hacker Tools, Techniques, and Incident Handling

Experience SANS training through course previews.
Learn MoreLet us help.
Contact usConnect, learn, and share with other cybersecurity professionals
Engage, challenge, and network with fellow CISOs in this exclusive community of security leaders
Become a member for instant access to our free resources.
Sign UpMission-focused cybersecurity training for government, defense, and education
Explore industry-specific programming and customized training solutions
Sponsor a SANS event or research paper
We're here to help.
Contact UsIn this article we'll look at some rules for working with string substitution, and some examples to leverage in your own PowerShell scripts.
When working with variables in PowerShell, you can leverage built-in support for PowerShell variable string substitution. In this article we'll look at some rules for working with string substitution, and some examples to leverage in your own PowerShell scripts.
String substitution is something you will use in scripts and other short PowerShell 1-liners where you have a variable that you want to expand in a message. For example:
PS C:\Users\Sec504> $name = Read-Host "Tell me your name"
Tell me your name: Josh
PS C:\Users\Sec504> Write-Host "Nice to meet you, $name"
Nice to meet you, Josh
Instead of using string concatenation to merge static strings and variables together, you can embed the variable inside of the quoted string. There are a few rules though:
PS C:\Users\Sec504> $name = Read-Host "Tell me your name"
Tell me your name: Mick
PS C:\Users\Sec504> Write-Host 'Nice to meet you, $name'
Nice to meet you, $name
Rule 1: Variables are expanded in strings with double quotes.
If you specify a string with single quotes, it will treat the variable [code]$name[/code] a literal value, and not a variable to substitute. Also:
PS C:\Users\Sec504> Write-Host "Do you love PowerShell, $name?"
Do you love PowerShell,
PS C:\Users\Sec504> Write-Host "Do you love PowerShell, $name, or whoever you are?"
Do you love PowerShell, Mick, or whoever you are?
Rule 2: Add curly braces to be explicit around variable names
Some characters around variables are treated as part of the variable name, and not punctuation in the string, but this isn't always intuitive. The Microsoft documentation on PowerShell variables says:
In the case of [code]"Do you love PowerShell, $name?"[/code], PowerShell interprets the variable name as [code]$name?[/code], which doesn't exist and returns an empty string. In cases like this, you can surround the variable name in curly braces to force PowerShell to interpret the variable name in the way you want:
PS C:\Users\Sec504> Write-Host "Do you love PowerShell, ${name}?"
Do you love PowerShell, Mick?
Rule 3: Be careful with the backtick
PowerShell also offers support for escape sequences, starting with a backtick [code] [/code][code] followed by a letter. This is most often seen as [/code][code] [/code]n `` to add a newline:
PS C:\Users\Sec504> $age = Read-Host "Please enter your age.`nBe honest please"
Please enter your age.
Be honest please: 47
PS C:\Users\Sec504> Write-Host "The user is $age."
The user is 47.
The backtick can also be used to escape a literal character in a string. Let's say you needed to have a literal [code]"[/code] in your string -- you can escape the [code]"[/code] with a preceding backtick:
PS C:\Users\Sec504> $pass = Read-Host -AsSecureString "Enter your password (do not include `" in the string)"
Enter your password (do not include " in the string): **********
Let's apply these concepts into some practical examples.
Let's say you want to allow a user to specify a directory name, and you report on the number of files in the directory. Here's a short script, [code]countfiles.ps1[/code]:
$dirName = Read-Host "Enter the directory name"
$count = (Get-ChildItem -Path $dirName | Measure-Object).Count
Write-Host "There are $count files in the directory $dirName"
Invoking the script the user specifies the directory, and they get the answer. No string concatenation needed!
PS C:\Users\Sec504> .\countfiles.ps1
Enter the directory name: C:\Windows
There are 101 files in the directory C:\Windows
PS C:\Users\Sec504> .\countfiles.ps1
Enter the directory name: C:\Tools
There are 46 files in the directory C:\Tools
Let's say you have a script that is about to do something that is irrevocable, like deleting thousands of users from Active Directory. You might want to give the script user a heads-up, and a chance to terminate the script before the damage is done.
Write-Host "Press CTRL+C before the timer expires to stop the script."
For ($i = 9 ; $i -ne 0; $i--) {
Write-Host -NoNewline "$i`b" ;
Start-Sleep 1
}
Write-Host "Deleting users now..."
# Not actually deleting any users
These lines use a [code]ForEach-Object[/code] loop (shortened to [code]For[/code], here), decrementing the variable [code]$i[/code] from 9 to 0. The [code]Write-Host[/code] line suppresses the automatic newline with [code]NoNewline[/code] and moves the cursor back to the beginning of the line after displaying the current value of [code]$i[/code]. This gives us a dramatic countdown allowing the user to press CTRL+C to stop the script.
In this article we looked at a topic all PowerShell users should understand: string substitution. PowerShell allows us to expand the value stored in a variable within a string, often eliminating the need to perform string concatenation. There are a few rules though: the string must be specified in double quotes, it is sometimes necessary to surround the variable name with curly braces, and the backtick character has special meaning. Keep these rules in mind, and you'll be leverage this powerful feature in all of your future PowerShell work!
Until next time!
-Joshua Wright
Joshua Wright is the author of SANS SEC504: Hacker Tools, Techniques, and Incident Handling, a faculty fellow for the SANS Institute, and a senior technical director at Counter Hack.
As Senior Technical Director at Counter Hack and SANS Faculty Fellow, Joshua has advanced cybersecurity through ethical penetration testing, uncovering critical vulnerabilities across Fortune 500 companies and national infrastructure providers.
Read more about Joshua Wright