0% found this document useful (0 votes)
5 views

gopas-goc-216-02-powershell-intro

The document provides an introduction to PowerShell, detailing its history from version 1.0 to PowerShell 7, including installation instructions for both server and client editions. It covers the .NET framework versions associated with each PowerShell version, basic syntax, command execution, and variable handling. Additionally, it includes practical examples of commands, aliases, and data structures like arrays and hashtables.

Uploaded by

monejav154
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

gopas-goc-216-02-powershell-intro

The document provides an introduction to PowerShell, detailing its history from version 1.0 to PowerShell 7, including installation instructions for both server and client editions. It covers the .NET framework versions associated with each PowerShell version, basic syntax, command execution, and variable handling. Additionally, it includes practical examples of commands, aliases, and data structures like arrays and hashtables.

Uploaded by

monejav154
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

10. 1.

2022

PowerShell introduction
Ing. Ondřej Ševeček | GOPAS a.s. |
MCSM:Directory2012 | MCM:Directory2008 | MVP:Enterprise Security | CEH |
CHFI | CISA |
[email protected] | www.sevecek.com |

GOPAS: [email protected] | www.gopas.cz | www.facebook.com/P.S.GOPAS

History
▪ PowerShell 1.0
• must be downloaded as a beta version
▪ Windows PowerShell 2.0
• download for XP/2003/Vista/2008
• default in 7/2008R2
• installable in 8/2012/8.1/2012R2/10/2016/2019/2022 as a feature
▪ Windows PowerShell 3.0
• download for Vista/2008/7/2008R2
• default in 8/2012
▪ Windows PowerShell 4.0
• download for Vista/2008/7/2008R2
• default in 8.1/2012R2
▪ Windows PowerShell 5.0
• download for 7/2008R2/8/2012/8.1/2012R2
▪ Windows PowerShell 5.1
• download for 7/2008R2/8/2012/8.1/2012R2
• default in 10/2016/2019/2022
▪ PowerShell 7
• .NET Core
• download for 8.1/2012R2/10/2016/2019/2022

1
10. 1. 2022

Windows PowerShell GUI installation on server editions


(use Enable-WindowsFeature)

Windows PowerShell GUI installation on client editions


(use Enable-WindowsOptionalFeature)

2
10. 1. 2022

NET framework (netfx) versions


▪ netfx 2.0
• binary engine + libraries
• 3.0 updates + some new libraries
• 3.5 updates + some new libraries
• 3.51 updates + some new libraries
▪ netfx 4.0
• binary engine + libraries
• 4.5 updates + some new libraries
• 4.51 updates + some new libraries
• 4.6 updates + some new libraries
• 4.6.2, 4.7, ...
▪ net core (version 6)
• binary engine + libraries reworked
• copy-paste installation built within a product

PowerShell families vs. netfx


▪ PowerShell 1.0
• netfx 2.0
▪ Windows PowerShell 2.0
• netfx 2.0
▪ Windows PowerShell 3.0
• netfx 4.0
▪ Windows PowerShell 4.0
• netfx 4.0
▪ Windows PowerShell 5.0
• netfx 4.0
▪ Windows PowerShell 5.1
• netfx 4.0
▪ PowerShell 7.2
• .NET core 6

3
10. 1. 2022

#1 download and install PowerShell 7 (core version)

▪ download Windows 10 Universal C Runtime


• prerequisite for Windows 8.1/2012R2
▪ download PowerShell-7.msi
• checks prerequisites + modifies %path%
▪ download PowerShell-7.zip
• copy-paste ready
• ensure prerequisites manually
▪ x32 vs. x64 vs. ARM

PowerShell consoles
▪ Windows PowerShell
%windir%\System32\WindowsPowerShell\v1.0\powershell.exe
%windir%\System32\WindowsPowerShell\v1.0\powershell.exe -ver 2
• version 2.0
• version 4.0/5.0/5.1 including 2.0 if installed
▪ Windows PowerShell additional installation folder
• some modules
%programfiles%\WindowsPowerShell

▪ PowerShell 7
%programfiles%\PowerShell\7\pwsh.exe
• newer version always deletes the previous folders

4
10. 1. 2022

$psVersionTable (Windows PowerShell 5.1, 4.0 and 2.0)

$psVersionTable (PowerShell 7)

10

5
10. 1. 2022

Console handling notes

# whole command on a separate line


write-host 'Hello world'

# unfinished command on several lines


get-process | % {

write-host $_.name

} | select -unique

11

PowerShell ISE
▪ Windows PowerShell only
%windir%\System32\WindowsPowerShell\v1.0\powershell_ise.exe

▪ or use Visual Studio


▪ or use notepad :-)

▪ color coding .PS1, .PSM1, .XML

12

6
10. 1. 2022

ISE quick keyboard handling


▪ F8
• execute selected block only
▪ F5
• execute the whole script
▪ ctrl+3
• the "notepad" view
▪ ctrl+I
• the code view
▪ ctrl+D
• the console view
▪ ctrl+shift+arrows in console
• cursor movement
▪ ctrl+[+/-]
• change font size

13

PowerShell syntax basics

14

7
10. 1. 2022

Comments

# single line comment

Get-Process # comment until the end of the line

<#
block comment
until the closing symbol
#>

15

Commands (executables)
# .exe found under one member of the %path% variable
ipconfig

ipconfig /all
ipconfig "/all"
ipconfig '/all'

# use of the -/ (dash/slash) depends on internal EXE


implementation
ipconfig -all

16

8
10. 1. 2022

Commands (executables)
nltest /sc_verify:gps

# the executable does require / (slash) parameters


nltest -sc_verify:gps

# quotes get resolved yet before being passed to the


executables
nltest /"sc_verify":"gps"

# apostrophes get resolved the same as quotes


nltest /'sc_verify':'gps'

# program failure may return an error code


nltest /sc_verify:invalid
$lastExitCode

17

Note the real parameter value called to system

18

9
10. 1. 2022

Commands (executables)

# an executable outside of the %path% environment variable


T:\SysInternals\pslist.exe -accepteula

# path to an executable which contains spaces (TAB


completion by the console)
& 'C:\Program Files (x86)\Microsoft
Office\Office15\WINWORD.EXE'

# works with quotes as well if typed manually


& "C:\Program Files (x86)\Microsoft
Office\Office15\WINWORD.EXE"

19

Commands (executables)

# if the executable is a console application with standard


output, PowerShell waits for its completion. GUI
applications are started and then forgot

Start-Process notepad -Wait

Start-Process certutil -ArgumentList "-ping",


dc.gopas.virtual -Wait

20

10
10. 1. 2022

Commands (cmdlets)
# invocation of a method from a netfx .DLL library
Get-Process

Get-Service ; Get-Volume

# a default named parameter name omitted (positioned param)


Get-Process svchost

# a named parameter explicitly mentioned


Get-Process -Name svchost

# part of a named parameter name if unambiguous


Get-Process -Na svchost

21

Commands (cmdlets)
# note the various parameter sets
Get-Help Get-Process

# investigate various parameter usage and try to compare it


with the Get-Help documentation
Get-Process -Name svchost
Get-Process -Na svchost
Get-Process svchost
Get-Process svch*
Get-Process -Id 4

# fails with ambiguous parameter name (Id/InputObject)


Get-Process -I 4
# fails to find a process with name "4" (4.exe)
Get-Process 4

# such a parameter combination does not exist


Get-Process -Name lsass -IncludeUserName -ComputerName wfe

22

11
10. 1. 2022

Commands (cmdlets) and simple pipeline

Get-Process | Format-Table -Property Name, ID, WorkingSet, CPU


Get-Process | Format-Table Name,ID,WorkingSet,CPU
Get-Process | ft Name,ID,WorkingSet,CPU

Get-Service | Format-List -Property Name,Status,StartType


Get-Service | fl Name, Status, StartType

Get-Process -Nam system | fl -Property *

Get-Date
Get-Date | fl *

Get-Process svchost | Measure-Object

23

Aliases
Get-ChildItem
dir

Get-Process
gps

Get-WmiObject Win32_LogicalDisk
gwmi Win32_LogicalDisk

cls

Get-Alias dir,gps, 'gwmi', cls

# mkdir is a more complex function than just an alias


Get-Command mkdir

24

12
10. 1. 2022

Commands (netfx static methods and properties)


# static property of a netfx class
[DateTime]::Now
[Environment]::UserName

# static method of a netfx class


[Net.Dns]::Resolve('www.google.com')

[Text.Encoding]::ASCII.GetBytes('Hello world')

[IO.Path]::GetFileName('C:\temp\Training\starter.ps1')

# fully qualified namespace


[System.IO.Path]::GetExtension('C:\temp\Training\starter.ps1')

# use of a type alias for


[System.Text.RegularExpressions.Regex]::Match
[regex]::Match('my age is 19 years', '\d+')

25

Output redirection just as in CMD

ipconfig /all > C:\TEMP\Training\output.txt

Get-Process lsass >> 'C:\TEMP\Training\output.txt'

[DateTime]::Now >> "C:\TEMP\Training\output.txt"

26

13
10. 1. 2022

Constants and basic expressions


'hello world'

"hello world"

5.83

0x3E7

380MB
2GB

# failure, GB does not mean anything on its own


7 GB

5.83 * 17.4
39 / 15

27

Constants and basic expressions


390495094 / 1MB

'Hello' * 20

'Hello' + ' Ondrej ' + 'how are you?'

# & does not work as it does in Visual Basic or VBScript


'Hello' & ' Ondrej ' & 'how are you?'

# modulo
39 % 5

# you cannot divide by zero


39 / 0

# boolean values
$true
$false

28

14
10. 1. 2022

Array (collection) constants


54, 8, 29

@(11, 38, 29)

(3..8)

'Praha', 'Bratislava', 'Brno'

@('Praha', 9, 'Bratislava', 77.4, 'Brno')

# invalid floating point number spec usage


5,83

# arrays containing only a single item


,8
@(8)

29

Variables (variant, no type fixed)


$myName = 'Kamil'

$myAge = 42

$freeStorageOfMyNotebook = 17GB

$currentInterest = 5.83

$expressionResult = 38 - 11

$sentence = 'Hello' + ' my ' + 'friend'

# no problem accessing a non-existent variable


$nonExistentVariable

$counter = 5
$counter ++
$counter = $counter + 3

30

15
10. 1. 2022

Variables and variant types

$myName = 'Kamil'
$myName

# no type checks performed


$myName = 38
$myName

$myName = 5.83
$myName

$myName = Get-Process
$myName

31

Command output into a variable

# textual output from the EXE is output into the variable


$outIPConfig = ipconfig /all
$outIPConfig

# command error codes go into the $lastExitCode variable


$outCertUtil = certutil -ping data
$outCertUtil
$lastExitCode

32

16
10. 1. 2022

Automatic type casting in expressions

'Kamil is ' + 27

# cannot convert string to a number


27 + ' years old Kamil'

35.7 + '22.8'

# converts 35.7 to a string resulting in 22.835.7


'22.8' + 35.7

33

Array (collection) variables

$names = @('Kamil', 'Jitka', 'Tana')


$names[0]

# just no problem
$names[3]

$names = $names + 'Stanislav'


$names[0]
$names[3]

34

17
10. 1. 2022

Hashtable (key-value pairs)

$cities = @{ 'Praha' = 1.2; 'Bratislava' = 0.43; 'Brno' =


0.38; 'Stockholm' = 0.98 }

$cities['Stockholm']
$cities['Paris']

# does not contain a key with value of 1


$cities[1]

# string comparison is case insensitive


$cities['stockHOLM']

35

Hashtable (key-value pairs)

$students = @{ 23 = 'Marie'; 1 = 'Kamil'; 17 = 'Daniel'; }

$students[1]

# no result, no problem, just no key with value of 19


$students[19]

# no result because there is no key with the string value


$students['1']

36

18
10. 1. 2022

Strings and variable expansion

$myName = 'Kamil'
$freeStorageOnMyNotebook = 17GB

# here the variables get expanded correctly inside quotes


"My name is $myName and I have $freeStorageOnMyNotebook
bytes free"

# but you have to use quotes instead of apostrophes


'My name is $myName and I have $freeStorageOnMyNotebook
bytes free'

37

Strings and variable expansion

$myName = 'Kamil'
$freeStorageOnMyNotebook = 17GB

# you also must be careful about the variable names


"My name is $myName and I have $freeStorageOnMyNotebookbytes
free"

# but you can still solve the problem with parentheses


"My name is $myName and I have
$($freeStorageOnMyNotebook)bytes free"

# do not use quotes generally


"Pa$$w0rd"

38

19
10. 1. 2022

Strings and variable expansion

$myBrothersAge = 40

# which you can also use in a more comple manner


"My current age is $($myBrothersAge + 2) years"

# again, it will not work with apostrophes


'My current age is $($myBrothersAge + 2) years'

39

Strings with escape sequences


# double the quotes or ampersands to escape them
"Say ""hello"" to everyone"
"Say 'hello' to everyone"
'Say ''hello'' to everyone'
'Say "hello" to everyone'

# you can put special characters into quote string


"Longer text`r`nwich gets split`r`non to several`tlines with
a`tTAB"

# this expansion does not happen inside apostrophe string literals


'Longer text`r`nwich gets split`r`non to several`tlines with
a`tTAB'

40

20
10. 1. 2022

Command parsing mode (as opposed to the


Expression parsing mode)
$weAreInterestedIn = 'notepad'

# when parsing in command mode, parameters get enclosed in


quotes automatically
Get-Process -Name $weAreInterestedIn

$weAreInterestedIn = 'host'
Get-Process -Name svc$weAreInterestedIn
Get-Process -Nam "svc$weAreInterestedIn"

mkdir nameWith$folder
mkdir 'nameWith$folder'

41

Command parsing mode (as opposed to the


Expression parsing mode)

# invalid process ID "3*254", use parentheses


Get-Process -Id 3*254
Get-Process -Id (3*254)

# invalid computer name "[Environment]::MachineName", use


parentheses
Get-Service -Computer [Environment]::MachineName
Get-Service -Comp ([Environment]::MachineName)

42

21
10. 1. 2022

Command parsing mode (as opposed to the


Expression parsing mode)

# invalid domain name, imagine parentheses enclosing the


whole parameter value
nltest /sc_verify:[Environment]::UserDomainName
nltest /sc_verify:([Environment]::UserDomainName)

nltest /sc_verify:$([Environment]::UserDomainName)
nltest "/sc_verify:$([Environment]::UserDomainName)"

43

Simple operators (expression parsing)


# true
15 -gt 8

# true
17 -lt 39

# true
'ondrej' -eq 'ONdreJ'

# false (case sensitive)


'ondrej' -ceq 'ONdreJ'

# true, *?[h-m]
'Praha' -like 'p*a'

# false (case sensitive)


'Praha' -clike 'p*a'

# true (regular expression, case insensitive)


'IP address is 10.10.0.11 on LAN' -match '\d+\.\d+\.\d+\.\d+'

44

22
10. 1. 2022

Logical operators (expression parsing)

$myAge = 26
$myBrothersAge = 22
$myHomeCity = 'Paris'

# true
($myAge -gt 20) -and ($myBrothersAge -gt 15)

# true
($myAge -gt 20) -or ($myBrothersAge -lt 60)

# true
$myHomeCity -ne 'Praha'
-not ($myHomeCity -eq 'Praha')

45

Binary operators

35 -bxor 119
119 -bxor 84
84 -bxor 35

# turn on the bit value 4 inside the number


35 -bor 4
196 -bor 4

# is the bit value 8 enabled?


192 -band 8
200 -band 8

46

23
10. 1. 2022

[string]::Format() operator

$myName = 'Kamil'
$freeStorageOnMyNotebook = 17GB

"Hello, my name is $myName and I still have $($


freeStorageOnMyNotebook)bytes free"

'Hello, my name is {0} and I still have {1}bytes free' -f


$myName, $freeStorageOnMyNotebook

47

[string]::Format() operator

'decimal number {0:D5} to 5 places' -f 399


'decimal number {0,7:D} left-padded to 7 places' -f 399

'hexa number {0:X8} to 8 places' -f 399

'floating point {0:N2} with .xx precision' -f 399.476450

# join array members into a single string using a separator


@('Kamil', 'Jitka', 3.85, 'Stanislav') -join ' | '
'Kamil', 'Jitka', 3.85, 'Stanislav' -join '|'

48

24
10. 1. 2022

Operators operator what operator what

case-insensitive
-eq -and logical and
equal
operator what
-ne not equal -or logical or
case-insensitive
-contains case-sensitive
array string search -ceq -not logical not
equal
case-sensitive
-ccontains case-sensitive
collection search -cne -xor logical xor
not equal
inverse -contains
-notcontains wildcard
collections/arrays -like -band binary and
* ? [k-p]
inverse -ccontains
-cnotcontains case-sensitive
collections/arrays -clike -bor binary or
wildcard
case-insensitive
-in
in a collection/array -match regex -bnot binary not
not a member of a
-notin case-sensitive
collection/array -cmatch -bxor binary xor
regex
case-sensitive
-cin, -cnotin
-in, -notin -gt greater than -f format string
-clt, -cgt, -cgt, case-sensitive
-cge string order -lt lower than -join join strings

-ge greater or equal -replace regex replace

case-sensitive
-le lower or equal -creplace
regex replace

note: -in, -notin, -cin, -cnotin did not exist in PS 2.0

49

ScriptBlock (syntax-validated PowerShell code


in a variable)
$validScript = { Write-Host 'Hello'; ipconfig
Get-Process
}
$validScript

& $validScript

# syntactically valid script may fail during execution


$validScript = { Write-Host 'Hello'; ipconfig
gwmi Win32_NonExistent
Get-Process
}
& $validScript

# invalid syntax will fail already during definition


$invalidScript = { Write-Host) 'Hello' ipconfig }

50

25
10. 1. 2022

Some predefined variables

$error.Clear()
Get-WmiObject Non_Existent
39/0
$error
$error[1]

$env:WINDIR
$env:ProgramFiles
$env:LOGONSERVER
$env:TEMP

$psVersionTable

51

Never use echo or Write-Output until you really


know what it does actually

# display text on screen


Write-Host 'hello Marie'

$myName = 'Kamil'
# formatted text with specific color
Write-Host ('My name is: {0}' -f $myName) -Foreground Green

52

26

You might also like