Scripts

Scripts are another element of our leveraging of PowerShell as an offensive tool, and most of the time, this is probably the most common way we will utilize PowerShell for most tasks.

PowerShell Scripts are usually identified by the “.ps1” extension, the “1” indicating not the version of PowerShell, but rather the PowerShell engine. For the most part, we’ll be dealing with the .ps1 file.

PowerShell scripts can contain as little as a few commands to automate some tasks or be as complex as to contain parameters, script arguments, loops, functions, and anything else related to the capabilities that PowerShell offers as a scripting language.

Running a powershell script is as simple as calling it from the powershell console, using the (dot-backslash) . notation for a script in our current directory*.

PS C:\> .\example.ps1
You may have to bypass the current execution policy (as shown earlier) before you execute the script of your choosing.

A very basic example of a PowerShell script which takes a file name as an argument would be something like the following:

Param(
    [Parameter(mandatory=$true)][string]$file
)
Get-Content "$file"

Now if we run this file while supplying the name of a file, in this case, “users.txt” which contains several usernames, we can see what happens:

.\example1.ps1 users.txt

If we run the script without arguments, PowerShell will ask us for the file, since “mandatory=$true” has been set for the parameter function in our script.

Alternatively, in regard to the example on the previous slide, rather than writing a .ps1 script file, we could also just create a variable “$file” for our users.txt file, and then call the “GetContent” script against our variable, directly from the shell:

PS C:\Users\user\Desktop> $file=“users.txt”
PS C:\Users\user\Desktop> Get-Content $file

PowerShell supports several “loop statements” which we can utilize for different tasks. As we saw with a previous example of the “ForEach-Object” cmdlet, we can use loop statements to iterate through files, PowerShell object collections, and even conduct port scans which we will cover in this section.

A “loop” is a programming or scripting function which iterates a statement, or condition based on specific boundaries. In other words, a loop will repeatedly execute code in its body until a conditional statements returns “False” or, returns no additional data.

PowerShell allows us to use a number of loop statements for our purposes:

• for()
• foreach()
• while()
• do {something} while()
• do {something} until()

And as we can with mostly everything in PowerShell, we can get help on any of those statements with the “Get-Help” cmdlet:

PS C:\> Get-Help about_Foreach
PS C:\> Get-Help about_For
PS C:\> Get-Help about_Do
PS C:\> Get-Help about_While

Loops are generally divided into two parts, a loop statement, and a loop body and will also contain variables as seen in the example below:

PS C:\> $services = Get-Service
PS C:\> foreach ($service in $services) { $service.Name }

In the first line, we’re creating a variable called “$services” which will return the Get-Service objects collection as a result of running the “Get-Service” cmdlet. We then use the “foreach()” loop statement to create a new variable “$service” to contain each resulting object of the $services variable, and finally, we’re telling PowerShell to return the name of each $service with the “.Name” property in the loop body, between the {} brackets.

Furthermore, we can use several built-in cmdlets for constructing loop statements, specifically the “ForEach-Object” and “WhereObject” cmdlets.

The previous example could be similarly accomplished by using the “Get-Service” and “ForEachObject” cmdlets and pipeline, as follows:

PS C:\> Get-Service | ForEach-Object {$_.Name}

The “Where-Object” cmdlet allows us to select objects within a collection based on their property values in regards to when used for a loop. In the following example, we’re using the “Get-ChildItem” cmdlet to list the contents of a “Powershell” directory, while piping that output to the “Where-Object” cmdlet with the -match parameter to only return files that contain “xls” within their name:

PS C:\> Get-ChildItem C:\Powershell\ | Where-Object {$_.Name -match "xls"}

A great example of a useful loop which the uses the “foreach” statement, is a TCP Port Scanner we can create entirely via the shell as a one-liner:

PS C:\> $ports=(81,444);$ip="192.168.13.250"; foreach ($port in
$ports) {try{$socket=New-Object
System.Net.Sockets.TcpClient($ip,$port);} catch{}; if ($socket -eq
$null) {echo $ip":"$port" - Closed";}else{echo $ip":"$port" -
Open"; $socket = $null;}}

We can just as well put the contents of the above, into a “ScanPorts.ps1” file in this case, for easy execution:

PS C:\Users\user\Desktop> .\Scan-Ports.ps1

Last updated