# Bootcamp: Powershell Olympics

## Getting Started with Powershell

1\) Enter the command `Write-Host 'Hello, PowerShell!'`, then press Enter.

```powershell
PS C:\Users\Sec504> Write-Host 'Hello, PowerShell!'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FeynyQQ1YWboCwch2GZAD%2FScreenshot.png?alt=media&#x26;token=28ccfb9c-c531-4d13-9671-a98ffd5c9b2d" alt=""><figcaption></figcaption></figure>

2\) PowerShell commands and parameters options are not case-sensitive. Press the up arrow to return to the previous command, then change Write-Host to read write-host (lowercase). Press Enter to run the command.

```powershell
PS C:\Users\Sec504> write-host 'Hello, PowerShell!'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FZwAYtCtIvtZU1tb166Bg%2FScreenshot(3).png?alt=media&#x26;token=3693eb6d-130a-4901-bb3b-3f4da9aedc54" alt=""><figcaption></figcaption></figure>

3\) PowerShell supports many different commands. Let's try another. Type Clear-Host then press Enter. You can also clear your screen by pressing CTRL+L.

```powershell
PS C:\Users\Sec504> Clear-Host
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FKcF1LvB3t5Pdgh1Wxr2J%2FScreenshot(4).png?alt=media&#x26;token=c66a22f8-df12-46e1-9d0c-86870c17ea5d" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FWrx5KH2nwI6BuEZnvO3A%2FScreenshot(5).png?alt=media&#x26;token=0692bc85-ee46-4cd1-81a6-203a668548b1" alt=""><figcaption></figcaption></figure>

4\) Next, let's try a different PowerShell command: `Get-ChildItem`. This command lists files and objects.

```powershell
PS C:\Users\Sec504> Get-ChildItem
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F1KBxivtbnvXAiRoz662y%2FScreenshot(6).png?alt=media&#x26;token=4bd208b9-9064-457d-927e-80c46c183dc8" alt=""><figcaption></figcaption></figure>

5\) Use tab completion to run the `Get-NetAdapterAdvancedProperty` by typing just a few characters, then press Enter.

```powershell
PS C:\Users\Sec504> Get-NetAdapterAdvancedProperty
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FhdVXjxxA6JeYBEnVzImb%2FScreenshot(7).png?alt=media&#x26;token=3e8cf63f-2b8e-4fab-8ad5-ed298b972a04" alt=""><figcaption></figcaption></figure>

6\) Use `Get-ChildItem` to list the contents of the C:\Program Files (x86) directory by typing just a few characters

```powershell
PS C:\Users\Sec504> Get-ChildItem 'C:\Program Files (x86)\'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FPlHfDxaDZUfAipntngcB%2FScreenshot(8).png?alt=media&#x26;token=4ac3c3ed-f8e7-41ed-bb0d-9e26ae08c730" alt=""><figcaption></figcaption></figure>

7\) Run `Get-Verb` to see a list of approved PowerShell verbs.

```powershell
PS C:\Users\Sec504> Get-Verb
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FWNjREwG0c6724YH2GXr9%2FScreenshot(9).png?alt=media&#x26;token=8d11f1e1-0816-4ec5-b948-4bce87056bfa" alt=""><figcaption></figcaption></figure>

8\) Next, let's look at some popular Verb-Noun PowerShell functionality. Run the `Get-Date` command.

```powershell
PS C:\Users\Sec504> Get-Date
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F0AkNUdCBIaRlBExQqT1j%2FScreenshot(10).png?alt=media&#x26;token=feac1705-d9cc-4a58-ac4e-8693d66e6130" alt=""><figcaption></figcaption></figure>

9\) Next, type `Get-Volume`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Volume
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FVMU0FOqJ2ntIyfnh66XL%2FScreenshot(11).png?alt=media&#x26;token=6f59a06e-a095-4fa7-b405-cfbae7814dca" alt=""><figcaption></figcaption></figure>

10\) Next, let's try a different verb. Type the `Start-Process Notepad`, then press Enter.

```powershell
PS C:\Users\Sec504> Start-Process Notepad
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fods5GsHUtZM7WIYDGWEq%2FScreenshot(12).png?alt=media&#x26;token=f2a7b43d-1e15-460c-ba20-dd5ecc53ce81" alt=""><figcaption></figcaption></figure>

11\) Next, let's look at the `Get-Process` command. Type `Get-Process Notepad`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Process Notepad
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FjkSmTvHReicwHdMhlHJh%2FScreenshot(13).png?alt=media&#x26;token=4176ec3f-aa20-4b9c-aaa0-4a577483cbb4" alt=""><figcaption></figcaption></figure>

12\) Next, type `Stop-Process Notepad`, then press Enter.

```powershell
PS C:\Users\Sec504> Stop-Process -Name Notepad
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FXVjeEsqNpbJUe6ipjmD0%2FScreenshot(14).png?alt=media&#x26;token=26cfde87-7604-47d6-ad35-7557892f4c8d" alt=""><figcaption></figcaption></figure>

13\) Let's investigate the `Start-Process` command further. We can use `Get-Command` to collect additional information about PowerShell commands. Type `Get-Command -Name Start-Process`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Command -Name Start-Process
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FIatrXwScmLvAGBuviYl2%2FScreenshot(15).png?alt=media&#x26;token=241c1292-0b91-4cc3-883f-10ba6a355118" alt=""><figcaption></figcaption></figure>

14\) Let's take a look at another command using `Get-Command`. Type `Get-Command -Name Get-Volume`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Command -Name Get-Volume
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fz3HkRSEy77LrYx0BEeVN%2FScreenshot(16).png?alt=media&#x26;token=a3eaf065-751c-4313-9460-b700ea8b252c" alt=""><figcaption></figcaption></figure>

15\) Type Get-Command -Noun Volume, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Command -Noun Volume
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FKTbLEI0lOaINnC7HSSby%2FScreenshot(17).png?alt=media&#x26;token=fabfe3a0-4f8f-48e5-83a3-a0d2e267bde5" alt=""><figcaption></figcaption></figure>

16\) Aliases are shortcuts to run PowerShell commands. Instead of Get-ChildItem, you can run the dir command.

```powershell
PS C:\Users\Sec504> dir
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FwVlWrCMKo9tIOif5WW6V%2FScreenshot(18).png?alt=media&#x26;token=b8f9a3b5-22b4-4db7-bbb1-93478f8aabc9" alt=""><figcaption></figcaption></figure>

17\) You can use the Get-Alias command to look up the command associated with an alias. Type Get-Alias Dir, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Alias Dir
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fl2Ugdr61gwukN8tsTk1Q%2FScreenshot(19).png?alt=media&#x26;token=8b56c4c4-35b4-425a-864f-aa8f2baab4ba" alt=""><figcaption></figcaption></figure>

18\) Type Get-Alias -Definition Get-ChildItem, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Alias -Definition Get-ChildItem
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FnxxFqrSRWGPZ9netra46%2FScreenshot(20).png?alt=media&#x26;token=980323de-b842-46ee-b459-e4b3e0569e62" alt=""><figcaption></figcaption></figure>

19\) Find an alias for Get-Timezone.

```powershell
PS C:\Users\Sec504> Get-Alias -Definition Get-TimeZone
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F0ThT6UD3lggdrIS38NnI%2FScreenshot(21).png?alt=media&#x26;token=4e3e240c-7838-4663-8673-97ef141dbb03" alt=""><figcaption></figcaption></figure>

20\) Next, find out which command uses the alias ps.

```powershell
PS C:\Users\Sec504> Get-Alias ps
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FqczrsZAoozKhjca0jZ4x%2FScreenshot(22).png?alt=media&#x26;token=8838d90e-3310-414c-8a95-dd502060a97f" alt=""><figcaption></figcaption></figure>

21\) Type Get-Help, then press Enter to display PowerShell's help system information.

```powershell
PS C:\Users\Sec504> Get-Help
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F5k8615jAAKopew7Asny0%2FScreenshot(23).png?alt=media&#x26;token=c9f79235-1688-4079-95de-352d3eb764b5" alt=""><figcaption></figcaption></figure>

22\) Get-Help also provides instructions for specific commands. Run Get-Help Get-Process to get help information for the Get-Process cmdlet.

```powershell
PS C:\Users\Sec504> Get-Help Get-Process
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FtpOPqo4XTcqB2kCW4SAX%2FScreenshot(24).png?alt=media&#x26;token=db2b1574-b0df-4505-9421-522cedc333d8" alt=""><figcaption></figcaption></figure>

23\) When you run Get-Help, the help information displays all at once. Most of the time, we want to read the help documentation one screen at a time. This is the behavior of the Help function.

Type Help Get-Process, then press Enter. Press the spacebar several times to get to the end of the help information, then run next to continue.

```powershell
PS C:\Users\Sec504> Help Get-Process
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FTCwlG5R90Gb4fhkh8Fwx%2FScreenshot(25).png?alt=media&#x26;token=858b29da-d888-4197-adde-b82ff5a6b8fc" alt=""><figcaption></figcaption></figure>

24\) But there's more! Type Get-Help -Examples Get-Process, then press Enter. Scroll up to scan through the help information.

```powershell
PS C:\Users\Sec504> Get-Help -Examples Get-Process
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FNac5PPTwNTEFOmS49hy8%2FScreenshot(26).png?alt=media&#x26;token=c292dfae-ee4c-4f8b-8dfb-0c787e96580f" alt=""><figcaption></figcaption></figure>

25\) PowerShell also provides high-level help information. Type Get-Help about\_Core\_Commands, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Help about_Core_Commands
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FSiLHKziFvu71tbDERWIO%2FScreenshot(27).png?alt=media&#x26;token=aa8e83d4-05e0-46bc-b22e-3caccfdf89f5" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Feu9eYG2fPkmwNK4U25xe%2FScreenshot(28).png?alt=media&#x26;token=7ad08671-ebb0-4653-b808-b1f5e19657cf" alt=""><figcaption></figcaption></figure>

26\) There are many other PowerShell about help subjects. Type Get-Help about\*, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Help about*
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F8yrfkDpz8CQayfPqapVz%2FScreenshot(29).png?alt=media&#x26;token=72a59660-d7d4-4b1d-8ada-601bfa169967" alt=""><figcaption></figcaption></figure>

27\) Type ping 127.0.0.1, then press Enter to use the ping.exe program.

```powershell
PS C:\Users\Sec504> PING.EXE 127.0.0.1
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fq3PfzMxCqZv7Wmr0yZeq%2FScreenshot(30).png?alt=media&#x26;token=33b8dc50-0d93-4953-97ca-ac34e6658502" alt=""><figcaption></figcaption></figure>

28\) Type sc query, then press Enter. PowerShell will prompt you for an option; press Enter when prompted.

```powershell
PS C:\Users\Sec504> sc.exe query
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FezjYLGq9di0qhyRRybO3%2FScreenshot(31).png?alt=media&#x26;token=35b77ad3-aaca-49ed-8c94-0bd51012c853" alt=""><figcaption></figcaption></figure>

## Working with the Pipeline

1\) Let's start with a straightforward command. Type `Get-Service`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Service
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F8hPpXFaLHFGjptwnDFD8%2FScreenshot(32).png?alt=media&#x26;token=36045e64-02b9-4e20-9c0e-d8113f719430" alt=""><figcaption></figcaption></figure>

2\) The Get-Service cmdlet allow us to interrogate the services running on the Windows system. There are a lot of services though, so it can be difficult to catch all of the output.

Press the up arrow to recall the `Get-Service` command. At the end of the line add a space followed by | more, then press Enter. Scroll through the output by pressing the spacebar multiple times until you return to the prompt.

```powershell
PS C:\Users\Sec504> Get-Service | more
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FdDWEzUG3epN6YiGereRj%2FScreenshot(33).png?alt=media&#x26;token=c6e9ecd0-9793-44bf-8576-9a0121dc8c2d" alt=""><figcaption></figcaption></figure>

3\) Use Sort-Object as a pipeline command to change the sort order of the Get-Service output to alphabetically descending. Type `Get-Service | Sort-Object -Descending`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Service | Sort-Object -Descending
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fr0FLpJ0eHUQcWSwGGfZr%2FScreenshot(34).png?alt=media&#x26;token=8eaddd44-1ba3-4760-8424-2381583f3578" alt=""><figcaption></figcaption></figure>

4\) Create a pipeline to sort the output of Get-Process by name. Type `Get-Process | Sort-Object -Property Name`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Process | Sort-Object -Property Name
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FLGHG13Qq9pyv79aIsATy%2FScreenshot(35).png?alt=media&#x26;token=2211c2fd-5476-48c6-8153-31d5e57d1619" alt=""><figcaption></figcaption></figure>

5\) In this output we see that `Sort-Object` has sorted the output by the Name property. You can also sort by process ID using the Id property.

```powershell
PS C:\Users\Sec504> Get-Process | Sort-Object -Property Id
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FtjfQoeIymsCiel7odihL%2FScreenshot(36).png?alt=media&#x26;token=51b0e64a-ac4d-4867-9c43-408da8447014" alt=""><figcaption></figcaption></figure>

6\) Sort-Object can also make the output unique. This can be useful to identifying the name of each item, eliminating duplicates.

Retrieve the process list again, sorting by name in alphabetically descending order. Add the `-Unique` argument to make the list of processes unique.

```powershell
PS C:\Users\Sec504> Get-Process | Sort-Object -Property Name -Descending -Unique
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FSXkB0TLH4wiGC0cNbPsO%2FScreenshot(37).png?alt=media&#x26;token=49d7329c-9e00-495d-a76b-f890d043acff" alt=""><figcaption></figcaption></figure>

7\) Like other shells, PowerShell supports redirection operators such as > to send the output of the pipeline to a file.

Run the PowerShell Get-Process, redirecting the output to a file in the default user profile directory called processes1.txt

```powershell
PS C:\Users\Sec504> Get-Process > processes1.txt
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FAdTHZHZ5VFeLXq0BLMDD%2FScreenshot(1).png?alt=media&#x26;token=caeaaae7-8851-4826-bb09-c38d85c4ae95" alt=""><figcaption></figcaption></figure>

8\) The redirection operator > allows us to create a file with the output of the pipeline, but we have little flexibility in defining the format of the file. This is where the cmdlet `Out-File` is useful.

Press the up arrow to recall the previous command. Instead of using the redirection operator, create a pipeline after Get-Process adding `Out-File -FilePath processes2.txt`

```powershell
PS C:\Users\Sec504> Get-Process | Out-File -FilePath processes2.txt
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FDmnMUMMSILWKUAhj8u0C%2FScreenshot(2).png?alt=media&#x26;token=2b7b4f8e-10ba-48ad-8134-3c0c8e8939bd" alt=""><figcaption></figcaption></figure>

8\) When you use the redirection operator > or Out-File, PowerShell takes the pipeline output and creates a little-endian UTF-16 unicode text file with a Byte Order Mark (BOM) at the beginning of the file. That is, these look like text files, but they aren't plain ASCII files.&#x20;

To create a plain ASCII text file, use `Out-File` with the parameter `-Encoding ASCII`. Run the previous command again, this time creating an ASCII file called processes3.txt

```powershell
PS C:\Users\Sec504> Get-Process | Out-File -FilePath processes3.txt -Encoding ascii
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FVD8yWoXJDajHXd1htvOZ%2FScreenshot(3).png?alt=media&#x26;token=1fc1cafa-60e4-4d80-a904-9c95478d9d64" alt=""><figcaption></figcaption></figure>

9\) Run `Get-ChildItem processes*` .Notice how the third file (the ASCII file) is approximately half the size of the other two. This is because UTF-16 format requires two bytes per ASCII character.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FZbBTZdOfLsT6mrO3kTyn%2FScreenshot(4).png?alt=media&#x26;token=413f389e-a24d-4133-a6b5-32647812f009" alt=""><figcaption></figcaption></figure>

10\) Examine the first several lines of the processes3.txt file. Type `Get-Content -Path processes3.txt -First 5`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Content -Path .\processes3.txt -First 5
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FPCQcCaUl6Wcui4MDKCmy%2FScreenshot(5).png?alt=media&#x26;token=5af966d7-ae7b-4301-aa69-c9cc06f1b883" alt=""><figcaption></figcaption></figure>

11\) No surprise here, the content of processes3.txt is just like what we saw when we ran Get-Process output in the terminal. Adding `Out-File` just redirects the output to a file.

What if you want the output to go to the screen and go to a file? This is the job of the Tee-Object cmdlet and the PowerShell pipeline. Type `Get-Process | Tee-Object -FilePath processes4.txt`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Process | Tee-Object -FilePath processes4.txt
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FjYVSvxBgf5bhuoCqEpiD%2FScreenshot(6).png?alt=media&#x26;token=41a32da8-6788-453b-b22a-97ffe3398fe6" alt=""><figcaption></figcaption></figure>

`Tee-Object` duplicated the output of `Get-Process`, showing it on the screen and saving it to processes4.txt

12\) PowerShell also supports other output mechanisms, such as `Export-Csv`. Create a list of processes, sending the output to the pipeline with `Export-Csv -Path processes.csv`.

```powershell
PS C:\Users\Sec504> Get-Process | Export-Csv -Path processes.csv
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FCFX5VOJWun4MAjWK98pU%2FScreenshot(7).png?alt=media&#x26;token=00d3630b-1e94-4adb-a8ef-23ad86b64dcb" alt=""><figcaption></figcaption></figure>

`Export-Csv` took the output of `Get-Process` and converted it into a CSV file, allowing us to process the data with other tools.

13\) Take a look at the first several lines of processes.csv using Get-Content. Limit the output to the first 5 lines.

```powershell
PS C:\Users\Sec504> Get-Content -Path .\processes.csv -First 5
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FxBuUPcJMyftHZEOqac3z%2FScreenshot(8).png?alt=media&#x26;token=ad709e84-d21a-4893-b710-c080cd248747" alt=""><figcaption></figcaption></figure>

This is a lot more information than what we saw when we used `Get-Process | Out-File`. Earlier we saw 8 columns of information but the CSV file has over 60 columns!

This highlights an important concept about the PowerShell pipeline: PowerShell passes objects in the pipeline, not  just text. An object is a collection of code (methods) and data properties that represents the item. Type next then press Enter to continue.

14\) This is an important concept. When you run a PowerShell command and send the output in a pipeline, you are sending an object or a collection of objects to the next step in the pipeline. These objects can include more information than what you see by default.

Using PowerShell, we can retrieve the information that is important to us using different commands. Let's try it now. Type `Get-Process -Name lsass | Select-Object -Property *`, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Process -Name lsass | Select-Object -Property *
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fm1DelqeK8mgF1klBIqyl%2FScreenshot(9).png?alt=media&#x26;token=25846445-66be-4b31-b0f1-86808bd8188c" alt=""><figcaption></figcaption></figure>

15\) Use `Get-Process` to collect the default properties for the rexplorer process.

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FUN0tMwgEBKjUteOqmBzJ%2FScreenshot(10).png?alt=media&#x26;token=7d545bd0-f2cd-494b-818c-f19c863b8fcd" alt=""><figcaption></figcaption></figure>

Get-Process shows some information, but let's gather more data. Let's examine summary information about the object returned by Get-Process using the PowerShell pipeline.

16\) Run `Get-Process -Name rexplorer | Measure-Object`

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Measure-Object
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FXBnpeydjycDI1DK7n1Fz%2FScreenshot(11).png?alt=media&#x26;token=14aa3a91-456d-48c1-a257-a41196373279" alt=""><figcaption></figcaption></figure>

Measure-Object returns information about the numeric properties of the objects received in the pipeline. In this example, `Measure-Object` tells us that there are 2 objects in the pipeline, corresponding to the two instances of the rexplorer process. We'll return to `Measure-Object` when we look at file processing.

17\) Next, let's look at the object members. Run Get-Process -Name rexplorer | Get-Member

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Get-Member
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FQYr6S65cDel2Bqw8QqQv%2FScreenshot(12).png?alt=media&#x26;token=7ff05bc2-21a3-4964-b51e-1b5f5aca33d6" alt=""><figcaption></figcaption></figure>

Get-Member returns information about the object properties and methods received in the pipeline. For `Get-Process`, we see lots of interesting properties about the processes, but no values.

18\) To see the values and the property names, run `Get-Process -Name rexplorer | Select-Object -First 1 -Property *`

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Select-Object -First 1 -Property *
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FEt0ddPqeiQLEbUWey7iB%2FScreenshot(13).png?alt=media&#x26;token=41edc2bf-3049-4ea9-9ab4-e41a1a5def5b" alt=""><figcaption></figcaption></figure>

In the previous command we used `Select-Object` to get a list of the properties available, limiting it to the first object returned with `-First 1` to avoid repeating the output for the two rexplorer processes. In this output we see the same property names that we saw with `Get-Member`, but we can also see the values for the first object.

This type of analysis is called introspection: the ability to examine properties of an object at runtime. We'll use Get-Member and Select-Object -Property \* often to see which properties are available when working with PowerShell objects.

19\) Let's retrieve specific properties about the rexplorer process using `Select-Object`. Instead of using `-Property *`, we can specify a comma-separated list of properties that we want to see.

Run `Get-Process -Name rexplorer | Select-Object -Property Name, Id, Path` to get the process name, process ID, and process path information.

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Select-Object -Property Name, Id, Path
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FHjnlRxegyOInc9cwm800%2FScreenshot(14).png?alt=media&#x26;token=dcc7b0a2-195d-4bbc-8bf0-9caaf9e6de8d" alt=""><figcaption></figcaption></figure>

20\) Repeat the last command by pressing the up arrow, then add two additional properties: CPU and WorkingSet64

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Select-Object -Property Name, Id, Path, CPU, WorkingSet64
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FDrmbhcvfmDE3XKAhC574%2FScreenshot(15).png?alt=media&#x26;token=61ced96f-1589-459a-a336-7a4c416e711f" alt=""><figcaption></figcaption></figure>

21\) Press the up arrow to recall the previous command and extend the pipeline, adding `Format-Table` as the last element.

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Select-Object -Property Name, Id, Path, CPU, WorkingSet64 | Format-Table
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FwZ91xaIYewrgYNBFMeVS%2FScreenshot(16).png?alt=media&#x26;token=5267d9c2-1986-442e-bb2b-4d3e292cb71b" alt=""><figcaption></figcaption></figure>

22\) Many of the associated PowerShell nouns work together in a pipeline. You can use a PowerShell command such as  `Get-Process`, then stop the target process by adding `Stop-Process` to the pipeline with no parameters.

Type `Get-Process -Name rexplorer | Stop-Process` then press Enter to terminate the rexplorer processes.

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Stop-Process
```

23\) Since PowerShell is designed around the concept of using a pipeline, there are lots of cmdlets that allow us to leverage this functionality. We can take the output of `Get-Process` and export the results to an HTML report using ConvertTo-HTML, for example.

Run `Get-Process | Select-Object -Property Name, Id, Path, CPU, WorkingSet64 | ConvertTo-Html | Out-File processes.html` to create an HTML report of all running processes, saving the output as processes.html

```powershell
PS C:\Users\Sec504> Get-Process | Select-Object -Property Name, Id, Path, CPU, WorkingSet64 | ConvertTo-Html | Out-File processes.html
PS C:\Users\Sec504> Start-Process .\processes.html
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FJiyUOrDnzpN6OPLrQ6R3%2F5978828058284638636(1).jpg?alt=media&#x26;token=e3864722-6199-4553-9c81-ff9d679a240f" alt=""><figcaption></figcaption></figure>

24\) Once you understand the concepts around PowerShell pipelines, it can be applied to lots of different functionality. For example, we can get basic information about the Event Log service by running `Get-Service -Name eventlog`

```powershell
PS C:\Users\Sec504> Get-Service -Name EventLog
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F07OFDJxYDXFPIZeXH5fZ%2FScreenshot(17).png?alt=media&#x26;token=027c19ca-6f77-4cca-b9a0-55f822066fa3" alt=""><figcaption></figcaption></figure>

25\) Press the up arrow to recall the previous command. Use `Select-Object` in a pipeline to retrieve the following fields about the Event Log service: Status, Name, DisplayName, and StartType

```powershell
PS C:\Users\Sec504> Get-Service -Name EventLog | Select-Object -Property Status, Name, DisplayName, StartType
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FNiikBn9BJYPTvxWdtDR3%2FScreenshot(19).png?alt=media&#x26;token=ef33126f-9c84-47bd-80fb-3d245d5b4794" alt=""><figcaption></figcaption></figure>

```powershell
PS C:\Users\Sec504> Get-Service -Name EventLog | Select-Object -Property *
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FRLGIYDJ23TRNIfzFUVbg%2FScreenshot(20).png?alt=media&#x26;token=09ef580f-4dc3-4117-b9a3-9ca0746f590b" alt=""><figcaption></figcaption></figure>

26\) Press the up arrow to recall that command, then display the results in a table format.

```powershell
PS C:\Users\Sec504> Get-Service -Name EventLog | Select-Object -Property * | Format-Table
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FZlu7uD7Yx1dzZEixIXHj%2FScreenshot(21).png?alt=media&#x26;token=a40ef0f6-fa4b-4fe3-aa80-697a42fb05d7" alt=""><figcaption></figcaption></figure>

27\) So far we've started out pipeline examples with `Get-Process` and `Get-Service`, but that doesn't have to be the start of the pipeline. Examine the status of the WinRM service: type `'winrm' | Get-Service` then press Enter.

```powershell
PS C:\Users\Sec504> 'winrm' | Get-Service
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FRnsjB9K9oIeMhP6bsSMA%2FScreenshot(22).png?alt=media&#x26;token=07041c02-b129-4e5e-be68-b5eb94125725" alt=""><figcaption></figcaption></figure>

In this command we created a string object 'winrm' as the input to the `Get-Servic`e cmdlet.

27\) Type `'winrm' | Get-Member` to see all of the string properties.

```powershell
PS C:\Users\Sec504> 'winrm' | Get-Member
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FiunltByUiQmQrq0hCDuN%2FScreenshot(23).png?alt=media&#x26;token=65a3154f-19be-4e95-9d96-346daf02bc10" alt=""><figcaption></figcaption></figure>

28\) Run `Get-Content -Path services.txt`

```powershell
PS C:\Users\Sec504> Get-Content -Path .\services.txt
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FdTEz238CgupLwTQBTQ58%2FScreenshot(24).png?alt=media&#x26;token=66ae2683-1b43-4ead-bdf6-07c0a29e7e2f" alt=""><figcaption></figcaption></figure>

29\) This file has several services listed. We can quickly interrogate all of the services by leveraging PowerShell parameter binding in the pipeline.

Press the up arrow to recall the previous `Get-Content` command, then add `Get-Service` to the pipeline.

```powershell
PS C:\Users\Sec504> Get-Content -Path .\services.txt | Get-Service
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FFM1UjI5vxHfT0eEgrRcH%2FScreenshot(25).png?alt=media&#x26;token=a963ada9-dace-46dd-9a3a-82b82bb97d34" alt=""><figcaption></figcaption></figure>

30\) Run `'rexplorer' | Stop-Process`&#x20;

```powershell
PS C:\Users\Sec504> 'rexplorer' | Stop-Process
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F0w7akbASqwlRmPo1xAZj%2FScreenshot(26).png?alt=media&#x26;token=8dbe3747-602f-418f-9584-2d8f246fad1e" alt=""><figcaption></figcaption></figure>

Stop-Process returns an error here, not because it doesn't support parameter binding (it does), but because it can't accept a string as the default parameter. However, you can build a pipeline starting with `Get-Process -Name rexplorer`, followed by `Stop-Process`. Do that now to stop the rexplorer process.

```powershell
PS C:\Users\Sec504> Get-Process -Name rexplorer | Stop-Process
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FAnsK39ttjcptmyxYHa94%2FScreenshot(27).png?alt=media&#x26;token=d78f784f-f66f-451c-b5d4-ed97b75703db" alt=""><figcaption></figcaption></figure>

31\) Get a list of running services using `Where-Object` by typing `Get-Service | Where-Object -Property Status -EQ Running`,  then press Enter.

```powershell
PS C:\Users\Sec504> Get-Service | Where-Object -Property Status -EQ Running
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FW12pPdL4DJ3hQlxcdiFg%2FScreenshot(28).png?alt=media&#x26;token=f4f2d6f8-7fd7-4020-9be4-82156f58a96f" alt=""><figcaption></figcaption></figure>

32\) Type `Get-Service | Where-Object -Property DisplayName -Like 'Application*'` then press Enter.

```powershell
PS C:\Users\Sec504> Get-Service | Where-Object -Property DisplayName -Like 'Application*'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FuPmswIObMyiOJ308w15b%2FScreenshot(29).png?alt=media&#x26;token=3c02e71e-7cd6-48e5-9666-21fb9d9ebb21" alt=""><figcaption></figcaption></figure>

33\) Use `Get-Process` to identify all processes running from a path that includes the string temp.

```powershell
PS C:\Users\Sec504> Get-Process | Where-Object -Property Path -Like "*temp*"
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FvdaAddjlgnkbkXkiNIpm%2FScreenshot(30).png?alt=media&#x26;token=50b13ad6-7bbc-4cd6-9a93-92857c2f3fbc" alt=""><figcaption></figcaption></figure>

Here we identifed all processes running from a directory with temp anywhere in the name. This is useful for incident response, since non-malicious processes rarely launch from temporary directories.

34\) Press the up arrow to recall the previous command. Use the pipeline to retrieve multiple details about these processes including the name, ID, path, and start time.

```powershell
PS C:\Users\Sec504> Get-Process | Where-Object -Property Path -Like "*temp*" | Select-Object -Property Name, Id, Path, StartTime
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F3vz0ewQvAMLgHMIUOw9q%2FScreenshot(31).png?alt=media&#x26;token=e200aecc-efcf-4032-b839-32a0f307eeb9" alt=""><figcaption></figcaption></figure>

35\) Now, extend the pipeline to sort the results by StartTime.

```powershell
PS C:\Users\Sec504> Get-Process | Where-Object -Property Path -Like "*temp*" | Select-Object -Property Name, Id, Path, StartTime | Sort-Object -Property StartTime
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fn0XorfgACcuEOnBJXU9Y%2FScreenshot(32).png?alt=media&#x26;token=6bcb61ef-abd7-404d-9963-f5bc59a6d6a3" alt=""><figcaption></figcaption></figure>

36\) Export this analysis into a CSV file named malicious-processes.csv and an HTML report named malicious-processes.html

```powershell
PS C:\Users\Sec504> Get-Process | Where-Object -Property Path -Like "*temp*" | Select-Object -Property Name, Id, Path, StartTime | Sort-Object -Property StartTime | Export-Csv -Path malicious-processes.csv
PS C:\Users\Sec504> Get-Process | Where-Object -Property Path -Like "*temp*" | Select-Object -Property Name, Id, Path, StartTime | Sort-Object -Property StartTime | ConvertTo-Html | Out-File -FilePath malicious-processes.html
```

37\) Next, terminate all of the processes running from temporary directories.

```powershell
PS C:\Users\Sec504> Get-Process | Where-Object -Property Path -Like "*temp*" | Select-Object -Property Name | Stop-Process
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F6oAulrqRcLaHlN5O5IxH%2FScreenshot(33).png?alt=media&#x26;token=8537de6d-b1d2-4ed2-9af0-7b25f7c5aa53" alt=""><figcaption></figcaption></figure>

39\) Remove the files starting with services in the file name.

```powershell
PS C:\Users\Sec504> Get-ChildItem -Name "services*" | Remove-Item
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FL44lTfNOJdFfs3P6TcVA%2FScreenshot(34).png?alt=media&#x26;token=cf1161a6-928a-4641-81cf-e89d3fe81334" alt=""><figcaption></figcaption></figure>

## Navigating Powershell Drives

1\) Navigating the file system is an essential skill for using PowerShell well. Start by examining your current directory.

Run `Get-Location` to examine your current directory.

```powershell
PS C:\Users\Sec504> Get-Location
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F2vY8dLCdre5TkVzVSFHz%2FScreenshot(35).png?alt=media&#x26;token=ef70cd3a-ed26-416b-b010-42ef35ceb1a3" alt=""><figcaption></figcaption></figure>

2\) You can also use the alias pwd for `Get-Location`. Try running the alias for `Get-Location` now.

```powershell
PS C:\Users\Sec504> pwd
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FTXaf7HX8P2FVuAPZTjvB%2FScreenshot(36).png?alt=media&#x26;token=367eea73-6e36-44b3-b74e-68cf58b3f4d3" alt=""><figcaption></figcaption></figure>

3\) In PowerShell you can use `Set-Location` to change to a different directory. Use `Set-Location` to change to the C:\temp\bobsled directory, then run `Get-Location` to display the current directory.

```powershell
PS C:\Users\Sec504> Set-Location C:\Temp\bobsled
PS C:\Users\Sec504> Set-Location C:\Temp\bobsled
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F3zXm8zpNSVKdZrSazFO4%2FScreenshot(37).png?alt=media&#x26;token=33745331-89ca-4fc2-a951-543f9f1c7e66" alt=""><figcaption></figcaption></figure>

4\) In the previous command you used an absolute directory reference, but PowerShell also supports a relative directory reference.

Use `Set-Location` to go back one directory by running `Set-Location ..` then run `Get-Location` to display the current directory.

```powershell
PS C:\Temp\bobsled> Set-Location ..
PS C:\Temp> Get-Location
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FSZynT95rfQ4G1omYiLhI%2FScreenshot(40).png?alt=media&#x26;token=fad11970-a5b2-4611-9250-c35d851d5a57" alt=""><figcaption></figcaption></figure>

5\) Next, return to the bobsled directory, this time using the relative path name with `Set-Location`, then run `Get-Location` to display the current directory.

```powershell
PS C:\Temp> Set-Location bobsled
PS C:\Temp\bobsled> Get-Location
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F6TRlIwZJtYdvIAzp3vcv%2FScreenshot(39).png?alt=media&#x26;token=a7c38a13-c960-40db-9f5d-e3441fda80f5" alt=""><figcaption></figcaption></figure>

6\) Next, let's create a new directory. Creating directories in PowerShell is the job of the `New-Item` cmdlet. To create a directory, specify `-ItemType` Directory and the name of the directory using -Name DirectoryName.

Use `New-Item` to create the directory sled (you need to already be in the C:\temp\bobsled directory).

```powershell
PS C:\Temp\bobsled> New-Item -Name sled -ItemType Directory
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FTOhrS23a3DDAfDxdbswE%2FScreenshot(41).png?alt=media&#x26;token=5ba8083e-6a7c-41c6-ae63-023a66d21ada" alt=""><figcaption></figcaption></figure>

7\) PowerShell will let you specify multiple directories in one command, creating each needed sub-directory. Run the `New-Item` command again, this time creating the following nested directories for a 4-person bobsled team: Brakeman\Pusher\Pusher\Pilot.

```powershell
PS C:\Temp\bobsled> New-Item -ItemType Directory -Name Brakeman\Pusher\Pusher\Pilot
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F4MvDCKeldUoxLsw9Wt9i%2FScreenshot(42).png?alt=media&#x26;token=d3f26775-f185-4743-b649-fe69d3809c51" alt=""><figcaption></figcaption></figure>

8\) The `New-Item` syntax to create directories can be simplified using the `mkdir` function: `mkdir DirName`. Create the directory structure using `mkdir` for a 2-person bobsled team: Brakeman\Pilot.

```powershell
PS C:\Temp\bobsled> mkdir Brakeman\Pilot
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FHwIKDszlIVuPKPrh89hq%2FScreenshot(43).png?alt=media&#x26;token=8e12f9ad-f673-4a29-a2fc-00c797a0c9b8" alt=""><figcaption></figcaption></figure>

9\) When you want to remove a directory, you can use `Remove-Item` followed by the directory name. Remove the sled directory using the `Remove-Item` cmdlet.

```powershell
PS C:\Temp\bobsled> Remove-Item .\sled
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FV0DxBBpB2bDpyldtGTbu%2FScreenshot(44).png?alt=media&#x26;token=e8f23648-4311-4269-adef-9762fc7e6ec8" alt=""><figcaption></figcaption></figure>

10\) PowerShell will prompt you if you try to remove a directory that has sub-directories or files in it. You can add the `-Recurse` argument to remove a directory and everything in it without a prompt. Remove the brakeman directory and sub-directories using `Remove-Item`. Add `-Recurse` to remove the directories without a prompt.

```powershell
PS C:\Temp\bobsled> Remove-Item .\Brakeman -Recurse
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FXkLxthxzdrDvGRIQyKFG%2FScreenshot(45).png?alt=media&#x26;token=9c3d8241-792d-4e5b-b7e1-922bf75d7311" alt=""><figcaption></figcaption></figure>

11\) Next we'll look at the powerful cmdlet `Get-ChildItem`. This cmdlet allows us to list items and child  items in one or more directories.Run the `Get-ChildItem` cmdlet with no arguments. Make sure you are in the C:\temp\bobsled directory. Note that we've added some files for your analysis.

```powershell
PS C:\Temp\bobsled> Get-ChildItem
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FUSIZbDHSJM5Btj4bVEh0%2FScreenshot(46).png?alt=media&#x26;token=1a91efd7-8bc9-4f4f-a0ac-311dd9e668ce" alt=""><figcaption></figcaption></figure>

12\) Get the content of the data folder. Use -Name also.

```powershell
PS C:\Temp\bobsled> Get-ChildItem data
PS C:\Temp\bobsled> Get-ChildItem -Name data
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FE4Oh6QjFniR50PRRi3QH%2FScreenshot(47).png?alt=media&#x26;token=67da0966-4bbf-410a-9648-5b3e3f553a0f" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FWEghPtGPk4ekc7n3D8cU%2FScreenshot.png?alt=media&#x26;token=fdd2765d-6560-4b58-a58a-5cbe377b832e" alt=""><figcaption></figcaption></figure>

13\) Run the previous command again, this time adding `-Recurse` to display file and directory names in all subdirectories.

```powershell
PS C:\Temp\bobsled> Get-ChildItem -Name data -Recurse
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F2EAX4FiiRl7TNQFNMdVK%2FScreenshot(1).png?alt=media&#x26;token=3aecd8eb-1f4a-4a23-bd3b-c97230cdd24d" alt=""><figcaption></figcaption></figure>

14\) Let's focus on the files in the data/1952 directory. Change to this directory, then run `Get-Location`. Then list the files in this directory.

```
PS C:\Temp\bobsled> Set-Location .\data\1952
PS C:\Temp\bobsled\data\1952> Get-Location
PS C:\Temp\bobsled\data\1952> Get-ChildItem
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FAiO7UdfoRHpM8QbyIaz7%2FScreenshot(2).png?alt=media&#x26;token=b55910e5-a53b-46d7-9295-a389f055ed49" alt=""><figcaption></figcaption></figure>

15\) By default, `Get-ChildItem` doesn't list files that have the hidden attribute set. To display hidden files, add the `-Force` argument. Run the previous command again, this time adding `-Force`.

```powershell
PS C:\Temp\bobsled\data\1952> Get-ChildItem -Force
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fk2FQVk4oMtLLrb0W04BC%2FScreenshot(3).png?alt=media&#x26;token=8eb2a9ff-fbca-4b9f-ac15-fc1f3e42024a" alt=""><figcaption></figcaption></figure>

16\) Using `Get-ChildItem` you can search for file or directory names by specifying a name as an argument. When you add `-Recurse`, you can search all subdirectories as well.

Search for the file named Hans\_He-GER-Bronze.txt.

```powershell
PS C:\Temp\bobsled> Get-ChildItem -Recurse 'Hans_He-GER-Bronze.txt'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fe3Qcqy5RmNB1QIwWe212%2FScreenshot(4).png?alt=media&#x26;token=585ad6d4-cce8-4582-bd0f-f1cf5db6f95f" alt=""><figcaption></figcaption></figure>

17\) You can also use the wildcard \* in the file name to perform partial name matches. Use `Get-ChildItem` with a wildcard to identify all Gold medal winners.

```powershell
PS C:\Temp\bobsled> Get-ChildItem -Recurse '*Gold*'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FeNLiLHcGnuzOhNAggG7G%2FScreenshot(5).png?alt=media&#x26;token=69851689-803f-4e1a-af8b-024a12b76004" alt=""><figcaption></figcaption></figure>

18\) PowerShell also allows you to exclude named with the `-Exclude` argument. PowerShell also allows you to exclude named with the `-Exclude` argument.

```powershell
PS C:\Temp\bobsled> Get-ChildItem -Name .\data\1998 -Exclude "*Gold*"
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FozmoHcMacJp9YgZQ1Vbv%2FScreenshot(6).png?alt=media&#x26;token=c96d4a12-2ad9-46ee-81d0-380c8b079592" alt=""><figcaption></figcaption></figure>

19\) The `Get-ChildItem` cmdlet is especially powerful, not just because you can list files and directories, but also because it allows you to examine other PowerShell Drives as well.

We normally think of drives as a drive letter (C:, E:, etc.), but PowerShell also supports other drive prefixes. Run  the `Get-PsDrive` cmdlet to see a list of PPowerShell drives on the system.

```powershell
PS C:\Temp\bobsled> Get-PSDrive
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F8YedbPMiOo4kWbQYeVZR%2FScreenshot(7).png?alt=media&#x26;token=fa555c25-8bc3-4658-8492-b02dd1b4fa79" alt=""><figcaption></figcaption></figure>

The output of Get-PSDrive shows us other PowerShell drive prefixes that we can also interrogate with Get-ChildItem.

20\) Examine the contents of the Env drive prefix using `Get-ChildItem`.

```powershell
PS C:\Temp\bobsled> Get-ChildItem Env:
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fldxv5WmxszHJbBbCQi3l%2FScreenshot(8).png?alt=media&#x26;token=0d29306d-fc6c-4e55-9d3d-0909e5e35bc2" alt=""><figcaption></figcaption></figure>

21\) Repeat the prior command, this time examining the contents of the HKCU PowerShell Drive.

```powershell
PS C:\Temp\bobsled> Get-ChildItem HKCU:
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FwUtCyd0lBxwUZMxbjCdH%2FScreenshot(9).png?alt=media&#x26;token=df423705-14a5-4ef0-94d1-a3a3375364ce" alt=""><figcaption></figcaption></figure>

HKCU is an alias for the Windows registry hive `HKEY_CURRENT_USER`. Since PowerShell treats this as a drive, we can use `Get-ChildItem` to interrogate the registry.

22\) Repeat the prior command, this time specifying the registry location HKCU:\Software.

```powershell
PS C:\Temp\bobsled> Get-ChildItem HKCU:\SOFTWARE
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FdyTjyOcJBJ2h9qfgUeYP%2FScreenshot(10).png?alt=media&#x26;token=363eb6b9-e69c-41f7-9835-850bfe8e555d" alt=""><figcaption></figcaption></figure>

23\) Here we see the Software registry key. Within this key we see several subkeys, including Microsoft. Repeat the prior command, this time examining the contents of the HKCU:\Software\Microsoft key.

```powershell
PS C:\Temp\bobsled> Get-ChildItem HKCU:\SOFTWARE\Microsoft\
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FyEgqstgYH5N8I4UP0gpo%2FScreenshot(11).png?alt=media&#x26;token=616a9b64-7846-438f-a7b6-bea3e6ef1997" alt=""><figcaption></figcaption></figure>

24\) As you can see, we can navigate the contents of the registry hive very much like we navigate a conventional file system. Examine the registry key values in the HKCU:\Software\Monobob2022 key.

```powershell
PS C:\Temp\bobsled> Get-ChildItem HKCU:\SOFTWARE\Monobob2022\
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FIGFYDxBWxQ8KxdLX6SF9%2FScreenshot(12).png?alt=media&#x26;token=81831b83-0ad4-47aa-a26c-c69a336e0d62" alt=""><figcaption></figcaption></figure>

25\) Repeat the last command, enumerating the contents of each of these registry keys by adding the `-Recurse` option.

```powershell
PS C:\Temp\bobsled> Get-ChildItem HKCU:\SOFTWARE\Monobob2022\ -Recurse
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F0eLp2uoZggmKq7PtdktI%2FScreenshot(13).png?alt=media&#x26;token=29d22d62-6a84-412d-bdf7-870d8665daff" alt=""><figcaption></figcaption></figure>

26\) Repeat the following command, this time adding the pipeline `Where-Object -Property Name -Match "Qing"` to find the key matching the Olymplic athlete name.

```powershell
PS C:\Temp\bobsled> Get-ChildItem HKCU:\SOFTWARE\Monobob2022\ -Recurse | Where-Object -Property Name -Match "Qing"
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fg0ARC14kuXH0zJYLweTL%2FScreenshot(14).png?alt=media&#x26;token=559dd961-9805-4942-884e-361f578a29e5" alt=""><figcaption></figcaption></figure>

27\) Next, let's investigate one more PowerShell Drive provider: system certificates. Use `Get-ChildItem` to examine the Cert: drive.

```powershell
PS C:\Temp\bobsled> Get-ChildItem Cert:
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fcp7SAibWx67fruVqNkY3%2FScreenshot(15).png?alt=media&#x26;token=0960c5a0-45c3-4cd7-85cb-ac3327df10d6" alt=""><figcaption></figcaption></figure>

28\) Examine the trusted root certificate authorities on the local system using `Get-ChildItem Cert:\LocalMachine\Root`

```powershell
PS C:\Temp\bobsled> Get-ChildItem Cert:\LocalMachine\Root\
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FU4sZipfJbXox3ahFvJCg%2FScreenshot(16).png?alt=media&#x26;token=5c6cd3ad-246b-4032-b1b4-b847b1abb1f4" alt=""><figcaption></figcaption></figure>

## Working with Powershell Variables

PowerShell has support for variables: named objects that hold data and code. First we'll look at PowerShell's automatic variables.

1\) PowerShell has several automatic variables available to every PowerShell session that describes the environment. Let's examine several of them.

```powershell
PS C:\Users\Sec504> $Host
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FHqpCm06Tx4yqbGAp7CT6%2FScreenshot.png?alt=media&#x26;token=c339d9bf-890f-45d5-b487-48805fdb0e4b" alt=""><figcaption></figcaption></figure>

2\) Examine the available members by typing `$Host | Get-Member`, then press Enter.

```powershell
PS C:\Users\Sec504> $Host | Get-Member
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FZ0orHoNPNfx1FzSj1PC7%2FScreenshot(1).png?alt=media&#x26;token=dd47dd8b-d205-4b2a-8b97-09dc50d35b2d" alt=""><figcaption></figcaption></figure>

The $Host variable is an object, just like everything else in PowerShell. Here we see the names of the properties and the methods. We can access these object members using dot notation.

3\) Access the Version property of the `$Host` variable: type `$Host.Version`, then press Enter.

```powershell
PS C:\Users\Sec504> $Host.Version
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FzxIBEb2CuL2CRZ9qj6MR%2FScreenshot(2).png?alt=media&#x26;token=ceb91b2b-496e-4cc8-a056-1ea305b37ddf" alt=""><figcaption></figcaption></figure>

Like $Host, $Host.Version is also a PowerShell object. Accessing this member shows the table format for the major, minor, build, and revision members. We can see all of the members in this object like we did for $Host using dot notation.

4\) Run the previous command with `Get-Member` .

```powershell
PS C:\Users\Sec504> $Host.Version | Get-Member
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FQxRLvXH5zgVmGSd0Imqv%2FScreenshot(3).png?alt=media&#x26;token=73526db5-2634-4094-a747-84978eeb60bd" alt=""><figcaption></figcaption></figure>

5\) Here we see the list of properties for the $Host.Version property. If you want to access just the Major value you can reference this member directly using more dot notation.

```powershell
PS C:\Users\Sec504> $Host.Version.Major
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Ff9v23ZwqFOVjuwoV4ppY%2FScreenshot(4).png?alt=media&#x26;token=6a6f7619-8c5c-4b76-b15b-e47403546cf3" alt=""><figcaption></figcaption></figure>

6\) You can also invoke the methods associated with the `$Host.Version` object by specifying the method name followed by () (sometimes with a value inside the parenthesis).

Invoke the `ToString()` method by typing `$Host.Version.ToString()`, then press Enter.

```powershell
PS C:\Users\Sec504> $Host.Version.ToString()
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FwPLyHgliHvmvD5pL6lAd%2FScreenshot(5).png?alt=media&#x26;token=e9c7a31e-5f00-43ca-a4b4-4f8c99eaacf0" alt=""><figcaption></figcaption></figure>

7\) Let's take a look at a few more useful variables. Type `$Home` then press Enter.

```powershell
PS C:\Users\Sec504> $HOME
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FUK92i96bgSeWvDf6LkJY%2FScreenshot(6).png?alt=media&#x26;token=2547ade7-33d1-49af-b4db-1f356ef1b7fe" alt=""><figcaption></figcaption></figure>

9\) We've created a file C:\TEMP\report.html; copy it to your user profile directory by typing `Copy-Item C:\TEMP\report.html $Home`

```powershell
PS C:\Users\Sec504> Copy-Item C:\Temp\report.html $HOME
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FaMDh1bfezaKrzd4koFtl%2FScreenshot(9).png?alt=media&#x26;token=b4645ab3-432a-499b-a6c2-2203ba165486" alt=""><figcaption></figcaption></figure>

10\) The `$Error` automatic variable keeps track of all the times your commands generated an error for the current session. This is valuable since your custom PowerShell programs can reference error messages to provide help to users.

```powershell
PS C:\Users\Sec504> good
PS C:\Users\Sec504> $Error
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FPzx0rSnRPkOipU4J0VCH%2FScreenshot(10).png?alt=media&#x26;token=d09a8a51-048e-449d-920f-e2c8ef388c33" alt=""><figcaption></figcaption></figure>

11\) We'll look at one more automatic variable: `$?`. First, run `Get-ChildItem -Name report.html`

```powershell
PS C:\Users\Sec504> Get-ChildItem -Name report.html
PS C:\Users\Sec504> $?
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FWIjBbG4zvfXe3ZSJhnhn%2FScreenshot(11).png?alt=media&#x26;token=418ad5d9-8f17-4da6-8e9c-ff2f1a70f341" alt=""><figcaption></figcaption></figure>

Notice how `$?` returns True. True is a Boolean data type; that is, it is either True or False. The `$?` variable indicates if the last command ran successfully. The output True here indicates that the `Get-ChildItem` command ran successfully.

12\) Let's look at another case: Type Get-ChildItem -Name report.txt, then press Enter. Then type `$?` .&#x20;

```powershell
PS C:\Users\Sec504> Get-ChildItem -Name report.txt
PS C:\Users\Sec504> $?
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FSmuDFrqIplTkoOqod4xz%2FScreenshot(12).png?alt=media&#x26;token=344d5b14-b2a0-4a4f-be1f-5eceb13c2b1e" alt=""><figcaption></figcaption></figure>

Notice how the value of `$?` is now set to False. This tells us the previous command did not run successfully. This is valuable in PowerShell scripts to test if the previous command returned an error. PowerShell has other automatic  variables as well, you can read about them by running `help about_Automatic_Variables`.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FuUtq4zizPOgJxY5STLXI%2FScreenshot(13).png?alt=media&#x26;token=ec606978-f5a8-4efc-84c4-14bef9a0724e" alt=""><figcaption></figcaption></figure>

13\) You may remember this from the PowerShell Olympics Using the Pipeline event. `Get-Process` retrieves a list of process details.

Run the command again, this time creating a variable name `$processes` to store the process information by typing `$processes = Get-Process`, then press Enter.

```powershell
PS C:\Users\Sec504> $processes = Get-Process
```

Type `$processes` and press Enter.

```powershell
PS C:\Users\Sec504> $processes
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FDr32MfGDERUrEGZMRUUq%2FScreenshot(14).png?alt=media&#x26;token=9e1d33a8-934f-446d-a726-59291373d244" alt=""><figcaption></figcaption></figure>

14\) Declare a new process information variable: type `$pnow = Get-Process`, then press Enter.

```powershell
PS C:\Users\Sec504> $pnow = Get-Process
```

We can compare the `$processes` and `$pnow` variables using `Compare-Object`. Type `Compare-Object $processes $pnow`, then press Enter.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F7iqN0LNq7yN6oT2vdHWm%2FScreenshot(16).png?alt=media&#x26;token=923bb845-146e-4ff3-af21-b095dd5170ea" alt=""><figcaption></figcaption></figure>

Notice how `Compare-Object` examines the two variables and shows us the differences? This is a powerful feature of PowerShell variables: they allow us to save a point-in-time representation of any object output, then compare it to another similar variable later.

15\) In the output of `Compare-Object` we see the rexplorer process is back. Type `$targetproc = Get-Process -Name rexplorer` then press Enter.

```powershell
PS C:\Users\Sec504> $targetproc = Get-Process -Name rexplorer
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FMlTtjU00MvJi8fR3TRAe%2FScreenshot(17).png?alt=media&#x26;token=2e6fab9d-e510-4944-a9f0-eb6c28317b19" alt=""><figcaption></figcaption></figure>

Notice how this time the variable holds just the process information for rexplorer, corresponding to the `-Name` argument of the `Get-Process` command. We can continue to leverage the features of different PowerShell commands as needed to refine what is represented in the variable.

16\) Use the PowerShell pipeline to examine the members of the `$targetproc` variable with `Get-Member`.

```powershell
PS C:\Users\Sec504> $targetproc | Get-Member
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FxdfZFLEH1IbaqEy93wcX%2FScreenshot(19).png?alt=media&#x26;token=df30e317-1d02-436b-b62e-771510de06f8" alt=""><figcaption></figcaption></figure>

Scroll up a bit and examine some of the methods and properties associated with the object. Notice the `Kill()` method that can be invoked to kill the processes identified in the `$targetproc` variable. Methods for an object can be invoked using dot notation `ObjectName.Method()`.

17\) Invoke the `Kill()` method on the `$targetproc` variable to terminate the two processes using dot notation.

```powershell
PS C:\Users\Sec504> $targetproc.Kill()
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FPQwzHCCIRRtMcSUZGzAs%2FScreenshot(20).png?alt=media&#x26;token=8e9df3ed-d134-4c86-b317-f8de9cb3c680" alt=""><figcaption></figcaption></figure>

By calling the `Kill()` method on the `$targetproc` variable you terminated both the rexplorer processes. You could have used the pipeline, sending the variable to `Stop-Process` as well; which one you choose is a matter of preference.

18\) Let's start by declaring a variable that represents a number. Type `$limit = 10`, then press Enter.

```powershell
PS C:\Users\Sec504> $limit = 10
```

19\) Like everything in PowerShell, `$limit` is an object. Take a look at the members of this object by running `$limit | Get-Member`

```powershell
PS C:\Users\Sec504> $limit | Get-Member
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FE7k4f5MJsStfY0rd2y8i%2FScreenshot(21).png?alt=media&#x26;token=12bfb74b-efcf-4afb-8f6e-813b2d097813" alt=""><figcaption></figcaption></figure>

At the top of this output look at the line starting with TypeName. When you declared the $limit variable with the value 10, PowerShell decided to use a type of Int32 (a 32-bit integer) to represent this data. The methods associated with this object are mostly for converting this to other types. Let's invoke one of those methods now.

20\) Type `$limit.GetType()` then press Enter.

```powershell
PS C:\Users\Sec504> $limit.GetType()
```

21\) PowerShell is a dynamically typed scripting language, which means that every variable has a type, but that variable type can change (it's dynamic). Let's experiment with that now: type `$limit = '100'` (with the quotation marks), then press Enter.

```powershell
PS C:\Users\Sec504> $limit = '100'
```

Press the up arrow a few times, recalling the `$limit | Get-Member` command, then press Enter.

```powershell
PS C:\Users\Sec504> $limit = '100'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F5wCR2DfesXQ45fAgb6LX%2FScreenshot(22).png?alt=media&#x26;token=290c8625-77cd-4c5f-a759-66531b4c06d5" alt=""><figcaption></figcaption></figure>

If you scroll up again you'll see the type has changed. This time, `$limit` is a String type with different methods and properties. When you specify quotation marks around a value, PowerShell will treat it as a string. Numbers assigned to a variable without quotations will be assigned a type of Int32 or other numeric types depending on the number selected.

22\) Next, let's look at something cool and useful. Type `$limit = 100MB`, then press Enter.

```powershell
PS C:\Users\Sec504> $limit = 100MB
PS C:\Users\Sec504> $limit | Get-Member
PS C:\Users\Sec504> $limit
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FM32IH5NqQ64Gwd6edXV4%2FScreenshot(23).png?alt=media&#x26;token=6a175dda-fff9-4a16-abb0-dc5925e21e4a" alt=""><figcaption></figcaption></figure>

Instead of `$limit` having a value of 100, it has a value of 104857600, the number of bytes in 100 MB. PowerShell is designed to be "administrator first", with handy integer literals to interpret values including kilobytes, megabytes, gigabytes, terabytes, and petabytes.

23\) PowerShell can also work with converting hexadecimal and binary values using the prefix 0x or 0b. Change `$limit` to 0x31337 now.

```powershell
PS C:\Users\Sec504> $limit = 0x31337
PS C:\Users\Sec504> $limit
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F3KLdvd9IJtufzMYZMTYB%2FScreenshot(25).png?alt=media&#x26;token=68f460cd-e54c-4c03-bf45-4caeed8eff93" alt=""><figcaption></figcaption></figure>

24\) Next, let's look at another type: arrays. PowerShell arrays hold zero or more elements denoted by `@()` notation. Create a PowerShell array: type `$alpinecourses = @('Rock', 'Ice River', 'Nile')` then press Enter.

```powershell
PS C:\Users\Sec504> $alpinecourses = @('Rock', 'Ice River', 'Rainbow')
```

Access the last element of the array. Type `$alpinecourses[2]`, then press Enter.

```powershell
PS C:\Users\Sec504> $alpinecourses[2]
```

Access the first element of the array.

```powershell
PS C:\Users\Sec504> $alpinecourses[0]
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fl2b7EmJxbiAYKhFgb6Bh%2FScreenshot(26).png?alt=media&#x26;token=36dda283-d892-4b21-ba73-33c90736f7fc" alt=""><figcaption></figcaption></figure>

25\) Retrieve a list of the Windows services using `Get-Service`, saving it in a variable called `$services`.

```powershell
PS C:\Users\Sec504> $services = Get-Service
```

Call the `GetType()` method on the `$services` variable.

```powershell
PS C:\Users\Sec504> $services.GetType()
```

The `$services` variable has a type of `Object[]`, but notice how the base type indicates that it is an array. We can use the array subscript notation to access different elements in this variable as well.&#x20;

```powershell
PS C:\Users\Sec504> $services[10]
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FAxuB4Lj0xTGauzazZ69A%2FScreenshot(27).png?alt=media&#x26;token=91d290e7-6d03-4885-979e-5938a1c36ca8" alt=""><figcaption></figcaption></figure>

26\) We'll look at one more variable type: DateTime. `Type Get-Date | Get-Membe`r, then press Enter.

```powershell
PS C:\Users\Sec504> Get-Date | Get-Member
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FiD3oc23MDtktmuP4mGX7%2FScreenshot(28).png?alt=media&#x26;token=6f31801a-597b-407c-a9e7-83fac9006171" alt=""><figcaption></figcaption></figure>

The PowerShell `Get-Date` command returns a DateTime type which represents the date and time when you invoke the command. We can use this command to record a start and ending time for an operation (such as a long-running job). Let's do that now.

27\) Create two variables, `$start` and `$stop` using `Get-Date`, with a delay of 3 seconds between using Start-Sleep 3. We'll use the command separator ; to run all three commands on one line. Type `$start = Get-Date ; Start-Sleep 3 ; $stop =  Get-Date` then press Enter.

```powershell
PS C:\Users\Sec504> $start = Get-Date; Start-Sleep 3; $stop = Get-Date
```

Subtract `$stop` from `$start` to see the time difference: `$stop - $start`

```powershell
PS C:\Users\Sec504> $stop - $start
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FZCK6qXDChnXuF4ILPcsS%2FScreenshot(29).png?alt=media&#x26;token=81ec0688-a294-4b4f-96ab-b99273dc140c" alt=""><figcaption></figcaption></figure>

The TotalSeconds property will show you the time delay between the two Get-Date commands, which will be just over 3 seconds. `Get-Date` will return the current date, but we can also specify an arbitrary date.

28\) Create a `$future` variable string of Feb. 8, 2030 at 9:00 AM (use MM/DD/YYYY or DD/MM/YYYY based on your regional convention; add a space after the year then 9:00 AM for the time).

```powershell
PS C:\Users\Sec504> $future = "08/02/2030 9:00 AM"
```

Try to subtract the `$start` object from `$future`.

```powershell
PS C:\Users\Sec504> $future - $start
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FYb0oyXQJK5LUnO7f6CmT%2FScreenshot(30).png?alt=media&#x26;token=4f71ec7c-3185-44d6-931f-fb12cc4a9d42" alt=""><figcaption></figcaption></figure>

We know that `$future` is a string object, since we declared it using quotes. We received an error because we can't perform arithmetic using a string and a DateTime object. We need to convert the string to a DateTime object using the cast operator.

29\) In PowerShell, you can specify a type in square brackets before the variable name to convert it to the specified type. Let's try that now.

Type `[DateTime]$future`, then press Enter.

```powershell
PS C:\Users\Sec504> [DateTime]$future
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FCn5u2Wxzjg9lX9aRIg16%2FScreenshot(31).png?alt=media&#x26;token=08b50726-1df4-4f15-a585-7f2031c1619f" alt=""><figcaption></figcaption></figure>

PowerShell converted the string in $future to a DateTime object.

30\) Press the up arrow several times to return to the subtraction operation and add a typecast to calculate the time span difference between `$future` and `$start`.

```powershell
PS C:\Users\Sec504> [DateTime]$future - $start
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FwdyF05Yy4Ba7kyE6d9wq%2FScreenshot(32).png?alt=media&#x26;token=92dbc108-2c82-4635-80cf-a80d6784ff23" alt=""><figcaption></figcaption></figure>

31\) PowerShell can easily embed variables inside of strings. To practice this, create a variable called `$favcolor` with a value of 'gold'.

```powershell
PS C:\Users\Sec504> $favcolor = 'gold'
```

Send a message to the console, using string substitution to expand the $favcolor variable. Type `Write-Host "My favorite color is $favcolor."`

```powershell
PS C:\Users\Sec504> Write-Host "My favorite color is $favcolor."
```

Press the up arrow to recall the last command and change the double quotes to single quotes, then press Enter.

```powershell
PS C:\Users\Sec504> Write-Host 'My favorite color is $favcolor.'
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F01eN5OlIsYHouSNsj904%2FScreenshot(33).png?alt=media&#x26;token=d50dc6cd-d5e6-414d-9311-6fdd93846f54" alt=""><figcaption></figcaption></figure>

32\) Along with string substitution, we also have escape sequences in strings. The backtick character is used to indicate an escape sequence, followed by an escape sequence character. For example, \`n is used to indicate a  newline.

We can create a prompt to accept user input with `Read-Host`. Type ``$age = Read-Host "Please enter your age.`nBe honest please"`` then press Enter. Enter a value when prompted, then press Enter.

```powershell
PS C:\Users\Sec504> $age = Read-Host "Please enter your age.`nBe honest please"
```

Here we used \` to indicate that a newline character should be inserted in the string. The `Read-Host` command prompts the user for input and saves it in the specified variable. Examine the contents of the `$age` variable to see your answer.

```powershell
PS C:\Users\Sec504> $age
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FvhN3ZDaYsdGwQTyqylJw%2FScreenshot(34).png?alt=media&#x26;token=b81531dc-fcf2-4f49-89f0-43979f8437d2" alt=""><figcaption></figcaption></figure>
