Windows CLI and Powershell Primer Guide

Cyber


Terminal Learning Objectives:

  1. Describe the differences between Object Oriented and Procedural programming shells

  2. Describe the Windows Command Shell and PowerShell

  3. Explain the role of the CLI in multiple operational roles

  4. Describe Powershell Profile Usage and Capabilities

  5. Examine the execution of a batch and PowerShell scripts

  6. Describe how PowerShell can be used to interact with Windows Management Instrumentation (WMI)

  7. Validate the security posture of the system by analyzing the patch level, configurations, and policies.



Introduction

Before the introduction of the Windows Graphical User Interface (GUI), in order to perform tasks or run programs you needed to manually type commands. Windows, while mostly interfaced with through the GUI, still allows users to complete tasks through the command prompt. You will hear the command prompt referred to by many different names; command prompt, cmd, shell, console window, or dos. We are going to explore some of the ways to interact with the Operatign System using the command prompt and PowerShell.


1. Object-Oriented and Procedural Programming Shells

TLOs: 1, 2, 3

Instructor note
(TLO) Describe the Differences Between Object-Oriented and Procedural Programming Shells
INTRO:
Discussion Question ; What is Procedural Programming?
Discussion Question; What is Object-Orientated Programming?

Introduction
In General:

  • In procedural programming, the program is divided into small parts called functions. In object-oriented programming, the program is divided into small parts called objects.

1.1 Object-Oriented Programming Defined

  • Object-oriented programming can be defined as a programming model which is based upon the concept of objects.

  • Objects contain data in the form of attributes and code in the form of methods.

  • In object-oriented programming, computer programs are designed using the concept of objects that interact with real world.

  • Object-oriented programming languages are various but the most popular ones are class-based, meaning that objects are instances of classes, which also determine their types.

  • Languages used in Object-Oriented Programming Include: Java, C++, C#, Python, PHP, JavaScript, Ruby, Perl, Objective-C, Dart, Swift, Scala.

Instructor Note:
Discussion Question:
Which type of language is powershell scripting, Object Orientated or Procedural Programming?

1.2 Shells considered Object Orientated

Windows PowerShell

  • PowerShell works with objects, and these objects can have attributes and methods. …​ PowerShell is an object-oriented scripting language; however, moderately complex scripts are often written using a procedural/functional approach.

1.3 Procedural Programming Defined

  • Procedural Programming can be defined as a programming model which is derived from structured programming, based upon the concept of calling procedure.

  • Procedures, also known as routines, subroutines or functions, simply consist of a series of computational steps to be carried out.

  • During a program’s execution, any given procedure might be called at any point, including by other procedures or itself.

  • Languages used in Procedural Programming Include: FORTRAN, ALGOL, COBOL, BASIC, Pascal and C.

1.4 Shells considered procedural

Unix/ Linux Shell Scripting

Instructor Note:
Discussion Question:
Which type of language is Unix/Linux Bash Shell Scripting; Object Orientated or Procedural Programming?

  • Shell scripting referring to the scripting language supported by shells derived from the Bourne shell on UNIX and UNIX-like systems are not an object-oriented language as they have no support for encapsulation, inheritance and polymorphism.

Windows CLI Batch Scripting

Instructor Note:
Discussion Question:
Is batch scripting object-oriented or Procedural Programming?

  • bat`or batch scripting by definition is not object-oriented; however, the power of the shell language is somewhat object-oriented.

  • If you are scripting in Python you can write your code as a simple script, used as functional programming, or object-oriented, your choice.


2. Command Shells

  • Windows has two command shells: The Command shell and PowerShell. Each shell is a software program that provides direct communication between you and the operating system or application. This provides an environment to automate OCO/DCO operations.

2.1 CLI in Multiple Operational Roles

  • CyberSpace Operations are defined into two general subsets by USCYBERCOM which are Defensive and Offensive Operations

  • Defensive Cyber Operations (DCO)
    Defined:
    To defeat specific threats that have bypassed, breached or are threatening to breach security measures.

  • Whereas tools exist (opensource and proprietary) which aide in automating some of the tasks required in DCO operations, the command line (CLI) is the primary tool for this purpose. The CLI allows for scripting and automation of tasks and is more often than not available on most operating systems. Possessing and maintaining a proficient level of skill with the CLI is a baseline requirement for successful operations.

  • Offensive Cyber Operations (OCO)
    Defined:
    To project power in and through foreign cyberspace.

  • OCO also utilizes a range of open-source and proprietary tool sets. OCO also requires CLI proficiency. Most times, initial entry or even long-term access to hosts require CLI in order to implement effects on target networks. The necessity to posses a strong CLI skill set is a baseline requirement.


2.2 Windows Command shell

CLI History Summary:

  • When Microsoft’s MS-DOS’ “Command-Line Interpreter” or “shell” was implemented it provided a simple, quirky, but relatively effective set of commands, and a command-scripting syntax for writing batch (.bat) files. MS-DOS was very rapidly adopted by businesses large and small, that, combined, created many millions of batch scripts, some of which are still in use today. Batch scripts are used to automate the configuration of users’ machines, setting/changing security settings, updating software, building code, etc. The Command shell was the first shell built into Windows to automate routine tasks, like user account management or nightly backups. Utilizing Windows Script Host you could run more sophisticated scripts in the Command shell. Command line interfaces (CLI) and prompts were the standard interface for computers from the early days into the 1980s. Current Windows systems offer the CLI for administrative tasks.


2.3 PowerShell

  • Powershell is a scripting language and functional command line shell which you can utilize either using Powershell.exe or using the PowerShell_ISE.exe (Interactive Scripting Environment). There are different versions of PowerShell, such as Powershell Core v6 which supports cross platform use for Linux/UNIX/Windows. Windows10 currently ships with PowerShell v5, which will be used in this class.

  • Today, PowerShell is commonly used in Network Enterprises to automate countless tasks at the server level and also at the client level for such things as Updates/Software Management/Security/3rd Party Software. Knowledge of PowerShell will help Cyber Operators understand/create/modify automated tasks to increase efficiency/security/speed/scaling of operations.


2.3.1 Transcript

  • We can turn on PowerShell transcripts to keep track of commands that have been run.

Currently the only downfall of PowerShell Transcript is that it does not work with PowerShell ISE.
start-transcript
start-transcript | out-null                       # Pipe to out-null so users don't see that commands are being recorded
Start-Transcript C:\MyWork.txt                    # Starts to log commands into the c:\mywork.txt file
Get-Service                                       # Run get-service command,and inputs the command and its results into the transcript
Stop-Transcript                                   # End the transcript
notepad c:\MyWork.txt                             # View the contents of the created transcript in Notepad


3. PowerShell Profile Usage and Capabilities

3.1 PowerShell Profiles

  • PowerShell profiles are a convenient way to store PowerShell configuration information as well as personalized aliases and functions to persistent use in every PowerShell session.

Profiles are just scripts that have configurations set.
  • PowerShell profiles were intended to assist PowerShell users with mundane repeatable tasks, such as loading a PowerShell module daily, or configuring . By default the profiles are not built, but the profile paths are always checked whenever PowerShell is opened.

PowerShell supports several profile files. The profiles below are listed in order of precedence, with the first profile having the highest precedence.
Description Path

All Users, All Hosts

$PsHome\Profile.ps1

All Users, Current Host - console

$PsHome\Microsoft.PowerShell_profile.ps1

Current User, All Hosts

$Home\[My]Documents\Profile.ps1

Current User, Current Host - console

$Home\[My ]Documents\WindowsPowerShell\Profile.ps1


In addition, other programs that host PowerShell can support their own profiles. For example, PowerShell Integrated Scripting Environment (ISE) supports the following host-specific profiles:

Description Path

All users, Current Host - ISE

$PsHome\Microsoft.PowerShellISE_profile.ps1

Current user, Current Host - ISE

$Home\[My]Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1


3.2 PowerShell $PROFILE Variable and Profile Paths

  • The $Profile automatic variable stores the paths to the PowerShell profiles that are available in the current session.

  • To view a profile path, display the value of the $Profile variable. You can also use the $Profile variable in a command to represent a path.

PS> $Profile
  • The $Profile variable stores the path to the "Current User, Current Host" profile. The other profiles are saved in note properties of the $Profile variable.

  • For example, the $Profile variable has the following values in the Windows PowerShell console.

$profile | Get-Member -Type NoteProperty                        # Displays the profile values of Names, MemberType, and Paths
$Profile | get-member -type noteproperty | ft -wrap             # Displays the same results but completed in case it was shortened with '...'
$PROFILE | Get-Member -MemberType noteproperty | select name    # Narrowed results to display only Names
  • Determine whether individual profiles have been created on the local computer:

Test-Path -Path $profile.currentUsercurrentHost
Test-Path -Path $profile.currentUserAllHosts
Test-Path -Path $profile.AllUsersAllHosts
Test-Path -Path $profile.AllUserscurrentHost
  • The profile paths include the following variables:

$PsHome         # Stores the installation directory for PowerShell
$Home           # Stores the current user’s home directory


3.3 Creating A PowerShell Profile

  • We can also create profiles for the current user in the current PowerShell host application.

New-Item -ItemType File -Path $profile -Force                 # Creates a $Profile for the CurrentUser. `Force` is used to ignore any errors.
ISE $profile                                                  # Opens your newly created $Profile, which is empty
  • By default, PowerShell aliases are not saved if you close a PowerShell window session.

    • For example, if you create a few aliases and close the PowerShell window, you will be required to recreate the same PowerShell aliases.

      • This would obviously present a problem if you have aliases set up for use in PowerShell scripts.


3.4 Commands and Arguments

The tab key is very helpful for file, command, and option completion. "Tab complete" increases your accuracy and speed.

Instructor Note
Discussion Question:
What types of commands does PowerShell use?

  • PowerShell uses cmdlets, which are unique to PowerShell.

    • PowerShell commands begin with a cmdlet name, followed by syntax, parameters, and arguments that control the output of the command.

    • Parameters always begin with a dash unless they are positional which do not require the dash.

  • They follow a verb-noun syntax pattern. Nouns are always singular e.g. Get-Process NOT Get-Processes

    • Example. Get-Service -name bits is the same as Get-Service bits the parameter has a dash but the positional or names parameter does not need one.

Get used to using a parameter rather than name until you can remember this.
  • Run the command Get-Help Stop-Service and the result will show

    • Stop-Service [-Name] <String[]> [-Exclude <String[]>] [-Force] as one of three syntax.

Don’t be confused by multitude of syntax, PowerShell has many.
  • The [] for -Name are the parameter, also the [] make it optional as a positional parameter. Arguments are surrounded by ( <> ) and describe data expected.

  • If an argument has [] inside the ( <> ) then it can take multiple. If [] surround the parameter and argument, it is optional.

  • Finally, PowerShell uses spaces as parameter delimiters.

    • If a parameter value contains spaces, then you must enclose the value in either single or double quotation marks.

Get-Content -Path "C:\Test Files\content.txt"                                         # Displays the contents of the file
Get-Variable                                                                          # Displays current Variables
Get-Verb                                                                              # List the PowerShell verbs
Get-Command                                                                           # List the PowerShell cmdlets
Get-Command -Type Cmdlet | Sort-Object -Property Noun | Format-Table -GroupBy Noun    # Get cmdlets and display them in order
Get-Command -Module Microsoft.PowerShell.Security, Microsoft.PowerShell.Utility       # Get commands in a module


3.5 PowerShell Help

  • There are several ways to get additional information on a powershell cmdlet.

Get-Help <cmdlet>                                                 # Displays help about a PowerShell cmdlet
Get-Help get-process                                              # Displays help for `Get-Process` cmdlet
Get-Help get-process -online                                      # Opens a web browser and displays help for the `Get-Process` cmdlet on the Microsoft website
Get-History <like Linux will return previous entered commands.>   # Displays history of commands in current window
Get-Location <similar to PWD on Linux, gl is the alias.>          # Displays present working directory
  • Alias man, like Linux will also return help. Using the -full or -detailed option will also increase help information.

  • The Help file will show the name of the cmdlet, a brief description, the syntax, and a longer description.

  • The About_ Help files contain information about scripting in PowerShell

    • When doing a get-help it searches the get-help page and the about_help page simultaneously but you can search the about_help page individually.

    • For a full list of about_help files. get-help about_

Get-Help about_command_syntax                                     # Displays help about command syntax


3.6 Alias

Instructor Note
Discussion Question:
Can I use Linux or cmd commands in PowerShell? If so, how?

View an Alias in PowerShell

Get-Alias <alias>                                                 # Displays aliases for a given command name
Get-Alias dir                                                     # Returns the alias for `dir`, `Get-ChildItem`

Create your own Alias: Example syntax

New-Alias -Name <Alias name> -Value Get-LocalUser


3.7 PowerShell Object Properties

Instructor Note
Discussion Question: What are Objects?

  • Objects are real things that have properties that describe attributes about them (what we know) and methods that control the object’s behavior/actions (what we can do).

    • When you run a PowerShell cmdlet, the cmdlet returns objects.

Everything in PowerShell is an object.
Get-Process | Get-Member                       # Gives the methods and properties of the object/cmdlet
  • The result is Get-Member returns the object type (TypeName)—in this case System.Diagnostic.Process.

    • There are numerous Typenames, for example, run Get-EventLog -LogName System | GM and notice the different Typenames as well as Membertypes.


(cmdlet).property                              # Command Structure
(Get-Process).Name                             # Returns the single property of 'name' of every process
Start-Process Notepad.exe                      # Uses the method Start to open notepad.exe
Stop-Process notepad                           # Uses the method Stop to close notepad.exe
Get-Process | Select-Object Name, ID, path     # Displays the Get-Process properties of 'Name, ID, Path' for every process
  • When a cmdlet is executed in PowerShell, the object is output in a default way.

    • You can format the data that you receive by piping the object through a format cmdlet format-table, format-list, etc

Get-Help Format-Table
Get-Help Format-List
When running commands be aware of '…​' at the end of lines, as this indicates there is more information. Try Format-Table -wrap


3.8 Using the Methods of Objects

  • Methods are actions that can be taken against an object.

Get-Process | Get-Member | Where-Object {$_.Membertype -match "Method"}       # Displays all objects with Method in their name from the results from Get-Member of the Get-Process cmdlet
Start-Process calc                              # Open an instance of calculator
(Get-Process calculator*).kill()                # Stops a named process using a method
Stop-Process -name calculator*                  # Same as above


3.9 Pipelined Variables

  • PowerShell allows for the properties and methods to be called within a pipe by using $_.(The Pipelined Variable)

    • The variable will always be of the same type as the object coming from the previous command.

Get-Process | Select-Object Name, ID, path | Where-object {$_.ID -lt '1000'}            # List all the processes with a PID lower than 1000
(Get-Process | Select-Object Name, ID, path | Where-object {$_.ID -lt '1000'}).count    # List all the processes with a PID lower than 1000


3.9.1 Pipelining

  • Objects in PowerShell are passed along in pipes (|) based off their inputted cmdlets

Get-LocalUser | Get-Member      # Displays properties and methods of the `Get-LocalUser` cmdlet


4. Batch Scripts

Description

  • A batch file is a script file that consists of a series of commands to be executed by the command-line interpreter and stored in a plain text file (.txt file) usually named (.cmd or .bat). A batch file may contain any command the interpreter accepts interactively and uses constructs that enable conditional branching and looping within the batch file. The term "batch" is from batch processing, meaning "non-interactive execution".

  • Batch Script is incorporated to automate command sequences which are repetitive in nature. Scripting is a way by which one can alleviate this necessity by automating these command sequences in order to make one’s life at the shell easier and more productive. In most organizations, Batch Script is incorporated in some way or the other to automate various tasks.

  • Batch scripts are stored in simple text files containing lines with commands that get executed in sequence, one after the other. These files have the special extension BAT or CMD.

Some of the features of Batch Script are:

    • Can read inputs from users so that it can be processed further
    • Has control structures such as: _for_, _if_, _while_, and _switch_ for better automating and scripting
    • Supports advanced features like functions and arrays
    • Supports regular expressions
    • Can include other programming codes like Perl

Some of the common uses of Batch Script are

    • Setting up servers for different purposes
    • Automating housekeeping activities, such as deleting unwanted files or log files
    • Automating the deployment of applications from one environment to another
    • Installing programs on various machines at once


Batch Scripting Structures
4.1 Creating Batch Files
  • Batch files are normally created in Notepad. Open Notepad and enter the commands required for the script.

Steps to create a Batch file:
    1. Create a new text file with the extension '.bat' to create a Batch file
    2. Now open the .bat file in any text editor, and start scripting


4.2 Batch Script Execution
  • There are two ways to execute a batch script.

    • Type the batch script in the command prompt by line
    • Write the code of script in a file and execute it through the command prompt
  • Typing commands over and over again in the terminal can be a very tedious task, if we have very lengthy code. So option two is generally preferred to create batch files.


4.3 Batch Commands
  • Basic batch commands are all case insensitive and can be used to perform a specific set of instructions

• DIR – The ‘dir’ command is used to get all the directories, sub-directories, and files present in the current working directory
• CD – The ‘cd’ command is used to change the current working directory
• VER – The ‘ver’ command tells the user's Windows version
• CLS – The ‘cls’ command is used to clear the shell's screen
• ECHO – The ‘echo’ command is by default ‘on’, but if we turn it off by ‘echo off’ it turns off prompt till the time ‘echo on’ is passed
• @ – The ‘@’ used before any command hides which command is running
• @ECHO OFF – This commands serves as the start point to any basic batch script, as it hides the prompt with ‘echo off’ and also hides the ‘echo off’ command with ‘@’
• HELP – This command tells us all about the commands available in the cmd shell. It runs only if the shell is ran as an Administrator

ECHO Command

@echo off
  • By default, a batch file will display its command as it runs. The purpose of this first command is to turn off this display. The command "echo off" turns off the display for the whole script, except for the "echo off" command itself. The "at" sign "@" in front makes the command apply to itself as well.

Set Command

  • Variables can be initialized via the ‘set’ command.

set /A variable-name=value
where
    • variable-name is the name of the variable you want to set
    • value is the value which needs to be set against the variable
    • /A – This switch is used if the value needs to be numeric in nature
  • Example

@echo off
set message=Hello World
echo %message%
  • In the above code snippet, a variable called "message" is defined and set with the value of "Hello World". To display the value of the variable, the variable needs to be enclosed in the % sign.

  • Output

Hello World


4.4 Working With Numeric Values
  • In batch scripting, it is possible to define a variable to hold a numeric value. This can be done by using the /A switch. The following code shows a simple way in which numeric values can be set with the /A switch.

@echo off
SET /A a = 5
SET /A b = 10
SET /A c = %a% + %b%
echo %c%

Output = 15
• We are first setting the value of 2 variables, _a_ and _b_ to _5_ and _10_ respectively
• We are adding those values and storing the output in the variable _c_
• Finally, we are displaying the value of the variable _c_
  • All of the arithmetic operators work in batch files.

@echo off

SET /A a = 5
SET /A b = 10
SET /A c = %a% + %b%
echo %c%

Output = 15

SET /A c = %a% - %b%
echo %c%

Output = -5

SET /A c = %b% / %a%
echo %c%

Output = 2

SET /A c = %b% * %a%
echo %c%

Output = 50


4.5 Arithmetic Operators
  • Batch script language supports the normal Arithmetic operators as any language.

Table 1. Arithmetic operators

Operator

Description

Example

+

Addition of two operands

1 + 2 will give 3

Subtracts second operand from the first

2 − 1 will give 1

*

Multiplication of both operands

2 * 2 will give 4

/

Division of the numerator by the denominator

3 / 2 will give 1.5

%

Modulus operator and remainder of after an integer/float division

3 % 2 will give 1


Table 2. Relational operators allow of the comparison of objects.

Operator

Description

Example

EQU

Tests the equality between two objects

2 EQU 2 will give true

NEQ

Tests the difference between two objects

3 NEQ 2 will give true

LSS

Checks to see if the left object is less than the right operand

2 LSS 3 will give true

LEQ

Checks to see if the left object is less than or equal to the right operand

2 LEQ 3 will give true

GTR

Checks to see if the left object is greater than the right operand

3 GTR 2 will give true

GEQ

Checks to see if the left object is greater than or equal to the right operand

3 GEQ 2 will give true


4.7 Logical Operators
  • Logical operators are used to evaluate Boolean expressions. The batch language is equipped with a full set of Boolean logic operators like AND, OR, XOR, but only for binary numbers. There are no values for TRUE or FALSE. The only logical operator available for conditions is the NOT operator.

Operator

Description

AND

This is the logical “and” operator

OR

This is the logical “or” operator

NOT

This is the logical “not” operator


=== 4.8 Command Line Arguments

*Batch scripts support the concept of command line arguments wherein arguments can be passed to the batch file when invoked. The arguments can be called from the batch files through the variables %1, %2, %3, and so on. The following example shows a batch file which accepts three command line arguments and echo’s them to the command-line screen.

@echo off
echo %1
echo %2
echo %3
  • If the above batch script is saved as a file named numbers.bat and we ran the file giving the arguments of 1 2 3:

> numbers.bat 1 2 3
1
2
3


Comments Using the Rem Statement+

*There are two ways to create comments in Batch Script; one is via the Rem command. Any text which follows the Rem statement will be treated as comments and will not be executed.

@echo off
Rem This program just displays Hello World
set message=Hello World
echo %message%
Output = Hello World


=== 4.10 Comments Using the

Statement

  • The other way to create comments in Batch Script is via the :: command.

Any text which follows the

statement will be treated as comments and will not be executed.

@echo off
:: This program just displays Hello World
set message = Hello World
echo %message%
Output = Hello World


Execute a Batch File
  • The following are the steps to execute a batch file

• Step 1 − Open the command prompt (cmd.exe)
• Step 2 − Go to the location where the .bat or .cmd file is stored
• Step 3 − Type the name of the file and press the Enter button to execute the batch file


5. PowerShell Scripts

Powershell Scripting Structures
  • PowerShell has a built-in scripting engine called PowerShell ISE. It is the ideal way to create scripts, as you have more control.

PowerShell Loops

  • PowerShell provides various control structures that allow for more complicated execution paths.

  • A Loop Statement allows us to execute a statement or group of statements multiple times. The following are the Help pages for loop statement in most of the programming languages.

Get-Help about_For
Get-Help about_Foreach
Get-Help about_While
Get-Help about_Do


Do Loop
  • The Do statement runs a statement list one or more times, subject to a While or Until condition.

    • The Do keyword works with the While keyword or the Until keyword to run the statements in a script block, subject to a condition.

      • A Do-While Loop is a variety of the While loop. In a Do-While Loop, the condition is evaluated after the script block has run. As in a While loop, the script block is repeated as long as the condition evaluates to true.

      • Like a Do-While Loop, a Do-Until Loop always runs at least once before the condition is evaluated. However, the script block runs only while the condition is false.


Do-While statement and Do-Until statement syntax

do {<statement list>} while (<condition>)
do {<statement list>} until (<condition>)

Do statement counts the items in an array until it reaches an item with a value of 0

C:\PS> $x = 1,2,78,0
C:\PS> do { $count++; $a++; } while ($x[$a] -ne 0)
C:\PS> $count
3

Until keyword with the Not Equal To operator (-ne) is replaced by the Equal To operator (-eq)

C:\PS> $x = 1,2,78,0
C:\PS> do { $count++; $a++; } until ($x[$a] -eq 0)
C:\PS> $count
3


For Loop
  • The For statement (also known as a For Loop) is a language construct you can use to create a loop that runs commands in a command block while a specified condition evaluates to $true.

    • A typical use of the For Loop is to iterate through an array of values and to operate on a subset of these values.

  • In most cases, if you want to iterate through all the values in an array, consider using a Foreach statement.

For statement syntax

for (<Init>; <Condition>; <Repeat>)
{
    <Statement list>
}

Iterates through an array separated by semicolons

$array = @("item1", "item2", "item3")
for($i = 0; $i -lt $array.length; $i++){ $array[$i] }
item1
item2
item3


Foreach Loop
  • The Foreach statement (also known as a Foreach Loop) is a language construct for stepping through (iterating) a series of values in a collection of items.

    • The simplest and most typical type of collection to traverse is an array.

  • Within a Foreach Loop, it is common to run one or more commands against each item in an array.


Display the values in the $letterArray

$letterArray = "a","b","c","d"
foreach ($letter in $letterArray)
{
  Write-Host $letter
}

Iterates through the list of items that is returned by the Get-ChildItem cmdlet

foreach ($file in Get-ChildItem)
{
  Write-Host $file
}


While Loop
  • The While statement (also known as a While Loop) is a language construct for creating a loop that runs commands in a command block as long as a conditional test evaluates to true.

    • The While statement is easier to construct than a For statement because its syntax is less complicated.

    • The While statement is more flexible than the Foreach statement because you specify a conditional test in the While statement to control how many times the loop runs.


While statement syntax

while (<condition>){<statement list>}

Displays the numbers 1 through 3 if the $val variable has not been created, or if the $val variable has been created and initialized to 0

while($val -ne 3)
{
    $val++
    Write-Host $val
}
#or
while($val -ne 3){$val++; Write-Host $val}


Loops Combined

A script with For/For-Each/While/Do Loops

for ($i = 1; $i -le 5; $i++) { Write-Host $i }
foreach ($i in Get-Alias) { Write-Host $i.name }
$i = 14
while ($i -gt 7) {
     Write-Host $i
     $i-=1
}
$i = 1
do
{
     Write-Host $i
     $i+=1
} while ($i -lt 7)


Error Messaging

Hiding Error Messages

Remove-Item does_not_exist.txt                                         # Displays errors in red
Remove-Item does_not_exist.txt -ErrorAction SilentlyContinue           # Hides any errors

Using Verbose Parameter to verify what we ran actually did something

New-Item -Type File it_exists.txt                                      # Creates a new file called 'it_exists.txt'
Remove-Item it_exists.txt -Verbose                                     # Returns a message notifying that it was deleted
Verbose only works on some CMDLETs with a specific Write-Verbose message field within their function.


PowerShell Conditions
  • PowerShell structures can have one or more conditions to be evaluated or tested by the script, along with a statement or statements that are to be executed if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.

    • In other words, run statement lists based on the results of one or more conditional tests.

If statement syntax

if (<test1>)
    {<statement list 1>}
[elseif (<test2>)
    {<statement list 2>}]
[else
    {<statement list 3>}]

Contains a single command statement. $a variable is greater than 2, the condition evaluates to true, and the statement list runs, and if false then it does not display

if ($a -gt 2) {
    Write-Host "The value $a is greater than 2."
}

Contains an else statement, a message is displayed when $a is less than or equal to 2. As the next example shows

if ($a -gt 2) {
    Write-Host "The value $a is greater than 2."
}
else {
    Write-Host ("The value $a is less than or equal to 2," +
        " is not created or is not initialized.")
}

An if statement can be followed by an optional else statement (elseif), which executes when the Boolean expression is false

if ($a -gt 2) {
    Write-Host "The value $a is greater than 2."
}
elseif ($a -eq 2) {
    Write-Host "The value $a is equal to 2."
}
else {
    Write-Host ("The value $a is less than 2 or" +
        " was not created or initialized.")
}


PowerShell Variables
  • PowerShell uses Variables as a unit of memory to store all types of values.

    • It can store the results of commands, and store elements that are used in commands and expressions, such as names, paths, settings, and values.

      • Variables are represented by text strings that begin with a dollar sign $, such as $a, $process, or $my_var.


User-Defined Variables
  • Variables created and maintained by the User

    • By default these exist only in the PowerShell windows that you have open (when they close, they are lost)

    • To save a variable, add it to your PowerShell profile

You can store any type of object in a variable, including integers, strings, arrays, and hash tables. And, objects that represent processes, services, event logs, and computers.

Retrieve list of current variables

Get-Variable                      # Names are displayed without the preceding <$>
Clear-Variable -Name MyVariable   # Delete the value of a variable
Remove-Variable -Name MyVariable  # Delete the variable

Creating a Variable

$MyVariable = 1, 2, 3             # Creates the MyVariable with 1,2,3

Creating a Variable of command results

$Processes = Get-Process          # Creates a variable with the results of Get-Process
$Today = (Get-Date).DateTime      # Creates a combined Date/Time variable from the results of Get-Date
  • The data type of a variable is determined by the .NET types of the values of the variable. To view a variable’s object type, use Get-Member.

How to find the data type

$PSHome | Get-Member              # Displays System.String with it's objects and properties
$A=12                             # Creating A with an integer
$A | Get-Member                   # Displays System.Int32


Automatic Variables
  • Automatic Variables are information about PowerShell that the system defines automatically, that are given values based on the condition or context at that particular point in time.

These variables are created and maintained by PowerShell.

Operator

Description

$$

Last token in the last line received by the session.

$?

Execution status of the last operation. It contains TRUE if the last operation succeeded and FALSE if it failed.

$^

First token in the last line received by the session.

$_

Contains the current object in the pipeline object. You can use this variable in commands that perform an action on every object or on selected objects in a pipeline.

$ARGS

Array of the undeclared parameters and/or parameter values that are passed to a function, script, or script block.

$ERROR

An array of error objects that represent the most recent errors.

$FALSE

Represent FALSE in commands and scripts instead of using the string "false".

$FOREACH

Enumerator (not the resulting values) of a ForEach loop. You can use the properties and methods of enumerators on the value of the $ForEach variable.

$HOME

Full path of the user’s home directory.

$LASTEXITCODE

Exit code of the last Windows-based program that was run.

$MATCHES

Works with the -match and -notmatch operators.

$NULL

Automatic variable that contains a NULL or empty value. You can use this variable to represent an absent or undefined value in commands and scripts.

$PID

Process identifier (PID) of the process that is hosting the current PowerShell session.

$PROFILE

Full path of the PowerShell profile for the current user and the current host application.

$PSVERSIONTABLE

Read-only hash table that displays details about the version of PowerShell that is running in the current session.

$TRUE

You can use this variable to represent TRUE in commands and scripts.

Get-Help about_automatic_variables


PowerShell Arrays
  • PowerShell provides a data structure, the Array, which stores a fixed-size sequential collection of elements of any type.

    • Arrays are simply data structures designed to a store collections of items.

The items in the array can be the same type, or different types.


Creating an Array

$A = 22,5,10,8,12,9,80

Calling the Array

C:\PS> Echo A$
22
5
10
8
12
9
80

Creating an Array with '..'

$a[1..4]
C:\PS> Echo a$
1
2
3
4

ForEach loop to display the elements in the $a array

$a = 0..9
foreach ($element in $a) {
  $element
}
#output
0
1
2
3
4
5
6
7
8
9

For loop to return every other value in an array

$a = 0..9
for ($i = 0; $i -le ($a.length - 1); $i += 2) {
  $a[$i]
}
#output
0
2
4
6
8

While loop to display the elements in an array until a defined condition is no longer true

$a = 0..9
$i=0
while($i -lt 4) {
  $a[$i];
  $i++
}
#output
0
1
2
3


PowerShell Functions
  • Functions allow quick-running custom code, rather than having to string multiple commands together every time you need them.

Get-Help about_Functions                                      # Displays the help about Functions
Get-Help about_Functions_Advanced                             # Displays some more in-depth help about Functions
Function Do-Stuff { Get-Date; Get-Process; Get-Service }      # Creates a Function with 'Get-Date, Get-Process, Get-Service' inside of it
Do-Stuff                                                      # Runs the Function


Functions are essentially a list of commands that serve a specific purpose.


PowerShell Comparison Operators
  • In PowerShell, Comparison Operators let you compare values or finding values that match specified patterns.

    • They also allow you to either compare two values or filter elements of a collection against an input value.

  • They can do the following:

    1 Equality
    2 Matching
    3 Replacement
    4 Containment
    5 Type
By default, all comparison operators are case-insensitive

Operator

Description

-lt

less than

-le

Less than or equal to

-gt

Greater than

-ge

Greater than or equal to

-eq

Equal to

-ne

Not equal to

-like

Like (uses wildcard for pattern matching)

-match

A match using Regular Expressions

Help and Comparison command format

get-help about_comparison_operators
Get-Service | Where-Object {$_.Status -eq "Stopped"}            # Takes the output from `Get-Service` and looks for the _status_ property of stopped services
Get-Service | where Status -eq "Stopped"                        # Same as above
Get-Process | Where-Object -Property Handles -GE -Value 1000    # Lists processes that have _greater than_ 1000 handles
Get-Process | where Handles -GE 1000                            # Same as above
Where Alias is Substituted for the Where-Object


Commenting in PowerShell
  • In PowerShell, single-line comments start with a hash symbol (), everything to the right of the will be ignored.

    • In PowerShell 2.0 and above multi-line block comments can be used.

  • Multi-line comments are typically used to add descriptive help at the start of a script, but also work to embed comment text within a command.

Get-Process # comment                                           # Creates a comment beside cmdlet
<# comment                                                      # Begins a multiline comment
|
|
comment #>                                                      # Ends the multiline comment


5. PowerShell and Windows Management Instrumentation (WMI)

5.1 Windows Management Instrumentation (WMI)

  • WMI is organized in namespaces, which are like folders that correlate to specific products or technology. The top “folder” of the WMI namespace is always called “root”.

  • WMI organizes its classes in a hierarchical namespace. To find useful information, you need to know a Class Name plus the Namespace where it lives.

Exploring Namespaces

  • WMI represents namespaces as instances of the class: __Namespace. This class starts with two underscores. All internal WMI classes are marked that way.

Finding Child Namespaces of a Namespace

PS> Get-CimInstance -ClassName __Namespace
Name             PSComputerName
----             --------------
mdm
ms_40c
Security
ms_410
power
ms_413
ms_409
TerminalServices
ms_407
  • To find real namespaces with potentially interesting classes in them, exclude any namespace name that starts with *“ms_” followed by at least two numbers.

Excluding Localization Namespaces

PS> Get-CimInstance -ClassName __Namespace | Where-Object Name -NotMatch '^ms_\d{2}'

Name             PSComputerName
----             --------------
mdm
Security
power
TerminalServices

Listing All Available Namespaces

  • To find all namespaces, you need to start the search at the top namespace root and then search recursively through all child namespaces.

  • Since recursion is hard to debug and has the risk of running into out-of-memory errors when nesting levels are too deep, a better alternative is using a Queue.

Some namespaces are protected, so in order to get a full list, make sure you run below code with Administrator privileges.
# create a new queue
$namespaces = [System.Collections.Queue]::new()

# add an initial namespace to the queue
# any namespace in the queue will later be processed
$namespaces.Enqueue('root')

# process all elements on the queue until all are taken
While ($namespaces.Count -gt 0 -and ($current = $namespaces.Dequeue()))
{
    # find child namespaces
    Get-CimInstance -Namespace $current -ClassName __Namespace -ErrorAction Ignore |
    # ignore localization namespaces
    Where-Object Name -NotMatch '^ms_\d{2}' |
    ForEach-Object {
        # construct the full namespace name
        $childnamespace = '{0}\{1}' -f $current, $_.Name
        # add namespace to queue
        $namespaces.Enqueue($childnamespace)
    }

    # output current namespace
    $current
}
  • The result on an average Windows10 client looks similar to this:

root
root\subscription
root\DEFAULT
root\CIMV2
root\msdtc
root\Cli
root\Intel_ME
root\SECURITY
root\SecurityCenter2
root\RSOP
root\PEH
root\StandardCimv2
root\WMI
root\MSPS
root\directory
root\Policy
root\Interop
root\Hardware
root\ServiceModel
root\SecurityCenter

-----Truncated-----
  • Listing Classes in a Namespace

  • Now that you know the names of the available namespaces, Get-CimClass can list the valid class names inside of each.

List class names for a namespace

# list all classes that live in namespace "root\cimv2"...
Get-CimClass -Namespace 'root\cimv2' |

# take only the class name...
Select-Object -ExpandProperty CimClassName |

# and sort the output:
Sort-Object

#putting it together
Get-CimClass -Namespace 'root\cimv2' | Select-Object -ExpandProperty CimClassName | Sort-Object
  • The result is a huge list: On an average Windows10 client, the namespace root/cimv2 contains 1,200 classes.

  • Identifying Useful Classes

  • Because there are so many WMI classes, it is important to define a strategy to identify potentially useful classes. The class name prefix can give a clue:

Prefix		Count	Description
__		    53		internal WMI class used to organize WMI
CIM		    286		Original class definitions
Win32	    749		Extended Microsoft implementations that inherit from a CIM class
MSFT		  102	  Unique Microsoft class that does not inherit from a CIM class
  • By excluding any class name that either starts with two underscores or with CIM_, you can eliminate a significant portion.

Exclude “Link” Classes

  • Classes can have relationships to each other, and these links are defined yet by other classes, similar to a database join. Typically, classes that just link two other classes have at most three properties. Any of these classes can be excluded.

Exclude Performance Counters

  • Every performance counter has its own WMI class, so if you are not explicitly trying to read performance counter values, exclude any classname that starts with Win32_Perf.

Exclude Plug&Play Classes

  • Another rather large group of classes describes plug&play functionality and starts with Win32_PnP. You can safely ignore these classes in most cases because the actual plug&play devices and most of the information about them surfaces in other more specific classes.

  • Reducing/Removing the "unwanted" classes will help in defining the target classes that might be useful to you.


5.2 CIM Classes

Instructor note
Discussion Question:
What are classes in PowerShell?

  • A class is like cats. There are many different kinds such as house cats, bobcats, lions, tigers and so on.

    • They are all cats, but each is unique.

Classes are a very general term for a grouping of similar objects.
  • Think of Common Information Model (CIM) classes as objects designed to control a specific windows subsystem like the Hard drive, or BIOS.

    • CIM Classes are the parent classes upon which WMI (Windows Management Instrumentation) classes are built.

    • While there are CIM classes of all sorts there may only be a few CIM instances actually being used.

Think of CIM class as place holder and CIM instance as an actual event.
Get-Cimclass *                                                                  # Lists all CIM Classes
Get-CimInstance –Namespace root\securitycenter2 –ClassName antispywareproduct   # Lists the antispywareproduct class from the root/security instance
Get-CimInstance -ClassName Win32_LogicalDisk -Filter “DriveType=3” | gm         # Shows properties and methods for this Instance
Get-WmiObject -Class Win32_LogicalDisk -Filter “DriveType=3”                    # Using the Windows Management Instrumentation method
CIM instances have unique methods and what they control
Be as specific when identifying the appropriate class for the command.
Get-CimInstance -class Win32_BIOS                      # Queries Win32_Bios
Get-WmiObject -Class Win32_BIOS                        # same output but deprecated command


Validate the security posture of the system by analyzing the patch level, configurations, and policies.

6. Patch Level and Configurations

Instructor note
Discussion Question:
Why is it important to know the patch level of a box? Response: Knowing the patch level is important from a DCO perspective to ensure your boxes are up to date. From an OCO perspective: When designing an exploit, it is necessary to know as much about your target as possible. If a host isn’t patched and up-to-date, you can find known vulnerabilities on that version of Windows.

6.1 Patch Level

Windows

  • list installed updates and their installation dates via PowerShell

> PS:\Get-Hotfix
  • view the update history via the command line

> systeminfo

linux

  • view the update history via bash

> uname -mrs


6.2 PowerShell Execution Policy

  • PowerShell uses .ps1 files as a way to run a series of PowerShell commands, with each command appearing on a separate line to make up a script.

    • By default policy is Restricted. This disallows all scripts not created in the local intranet zone aka the local machine or within a workgroup.

      • As a security concern, scripts can contain a host of malicious information and should require specific permissions and validation prior to execution.

Get-ExecutionPolicy -list                                             # Lists all of the Scopes and ExecutionPolicies on the system
Get-ExecutionPolicy                                                   # Gets the current user's ExecutionPolicy
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser  # Sets the ExecutionPolicy for the CurrentUser to Unrestricted


Summary

PowerShell and the Command Prompt are very resourceful and powerful tools for the Windows Operating System. They are designed to enabe a user to use the computer more efficiently. Keep in mind that these shells are meant for good/intentional interaction with the operatign system but can be used for nafarius reasons as well.