Table of Contents

Copied from Rob Sickler's Wiki

Powershell

Powershell is quickly replacing the Command Prompt as the go-to command line interface for many IT admins. While I don't think PS will ever replace CMD, I do feel it will come very close to doing so. For the most part, CMD was written for batch files and basic commands and, as such, has a fair amount of limitations. However, PS was built on the .Net Framework and is now open-source. Between the programming language back-end and the open source community support, PS has far more potential!

Basic Info from PS

Some commands only work in a certain environment. Some commands only work in certain versions. It important to know these things when you try to run various commands or need to troubleshoot scripts.

Version

Knowing the version of Powershell is important. Again, some commands may not work in certain versions. The Windows OS will ship with a version that can likely be updated over the life of the OS so don't think you're stuck with the same version forever.

Execution Policy

Checking and Setting the Policy

If you try to run a script, it may nag about the Execution Policy and fail to run. In those cases, you may need to set the policy appropriately or try bypassing it altogether.

Bypassing the Policy

Setting the Execution Policy on a system may not always be the way to go about it. Maybe you're in a production environment and, for security reasons, they don't want to allow PS scripts to run all the time. A good example of a scenario like this is one I worked in before. I ended up creating a Scheduled Task that called Powershell.exe from cmd.exe and did so with a parameter to bypass the policy - just for that execution.

You can call PS scripts or cmdlets right from the command line if needed however, although you can run long and complex commands this way, it can get messy rather quickly. For complex stuff, a script is usually easier to read and troubleshoot.

Aliases

Powershell has the ability to use aliases. You can even define your own! You may run across scripts that contain aliases and you may wonder what they stand for. Below, you'll find examples of how to go about finding aliases and what those aliases stand for. By and large, I don't like to use them in documentation due to readability reasons but I will use them to save some keystrokes when I'm doing something quick & dirty that I didn't write a script for.

For those of you who are playing along at home, if you ran all the commands I just mentioned, you probably saw something like this:

PS C:\WINDOWS\system32> Get-Alias -Name %
 
CommandType     Name                                               Version    Source 
-----------     ----                                               -------    ------ 
Alias           % -> ForEach-Object                                                  
 
 
PS C:\WINDOWS\system32> Get-Alias -Definition ForEach-Object
 
CommandType     Name                                               Version    Source 
-----------     ----                                               -------    ------ 
Alias           % -> ForEach-Object                                                  
Alias           foreach -> ForEach-Object

Putting Theory into Practice

Using an alias is easy enough; you just use it in lieu of the full cmdlet. For instance, the following three commands will do the exact same thing:

Working with the Filesystem

Working with Mapped Drives

Generally speaking, I hate mapped drives in corporate environments. Unless great care is taken to ensure consistency, they quickly become a mess. Think about it… When mapping a drive, you can choose any unused drive letter you want. So, I could map the network share, \\H2P-IOLWEB1\Code, to drive R:\ and tell you that the file you wanted was on said drive. However, you don't have that path mapped the same way I do or, in some cases, you don't have the path mapped at all! So, if I told you to take a look at R:\MyAwesomeScripts\MapDrive.ps1 for some great examples, you wouldn't be able to. Or, at best, you'd need to adjust your path. Moreover, if a path isn't available when the machine starts up, it can throw errors unless you've accounted for that as well. However, there are a few cases where a mapped drive is still useful. For instance, capturing a WIM file and dumping it to a network share from WinPE would be a good example of when using a mapped drive makes sense. You can also map drives via Group Policy and that would allow for some consistency. But, for the most part, I avoid mapped drives unless I'm in WinPE.

Copying Files and Folders

This is a very basic function for most people as they tend to just use Explorer to drag-and-drop. However, if you're on a Server Core machine or you're using remote commands through PS, you can copy files via other means.

Moving Files and Folders

Again, this is very basic but it helps to know how to do it via PS.

Deleting Files and Folders

Again, this is very basic but it helps to know how to do it via PS. Furthermore, this cmdlet can be used by many other providers so you can use it to delete files, folders, registry keys, variables, etc.

Renaming Files and Folders

This too is a simple task but it's handy to know how to do this via a quick command.

Working with ISOs and VHDs

Server 2012 has built-in support for mounting ISOs & VHDs. Sometimes you can just right-click one and mount the file. Worst case, you can also do this via Powershell.

Note that you may need admin access to mount VHDs.

Working with Processes

One can use PS to show running processes. It won't be real-time like what you'd see with Windows Task Manager but it's still helpful for easily finding the PID and other stats since the list won't be bouncing around as other processes come and go. It's even more helpful with processes on a remote machine since you don't need to RDP into it to check the running processes.

Showing Local Processes

Showing Remote Processes

Killing Local or Remote Processes

Killing a local process is very straight forward. Killing a remote process isn't as clean as I'd like it to be but it still works. So long as you have the correct permissions, killing a remote process can be achieved with the Invoke-Command cmdlet.

Working with Services

One can use PS to get info on services. It's also helpful with services on a remote machine since you don't need to RDP into it to check the running processes.

Showing Local Services

Showing Remote Services

As previously mentioned, this is handy for checking on services on remote machines.

Changing the Status of Services

Sometimes, you need to start, stop or restart a service on a local or remote machine1).

Working with Active Directory

PS can do all kinds of things in AD but I typically use it for quick and dirty reporting. From time to time, I'll also use it for bulk actions like cleaning up old computer and user objects.

If you're working on a Active Directory Domain Controller (ADDC), the tools should already be installed. However, if you're working on a Windows 10 client or another server that isn't an ADDC, it will likely be lacking the tools you need. In those cases, you'll likely need to install the Remote Server Administration Tools (RSAT) which is available for most modern Windows operating systems - servers and desktops alike. The tool kit has many tools for remotely managing Windows machines but, if you want to perform Active Directory management tasks, you need to - at the very least - install the proper bits to do so. Once you have the proper tools installed, and you have the correct permissions, you should be able to do most of what is written herein. The only other thing you may run into is whether or not you'll need to import the AD module in PS ahead of time. This, however, usually only pertains to older versions of PS and/or Windows. In those cases, you can just open PS and run the following to spin up the module:
Import-Module ActiveDirectory

Working with Computer Objects

List All Machines

List Computer Objects Based on OS

List Enabled or Disabled Computer Objects

Working with User Objects

List Information About User Objects

Working with AD Groups

List Groups

List Members of a Group

Add an AD Group

Clean up AD

Working with IIS

Using Powershell to Manage IIS

With IIS 7 and later, you can use Powershell to do a lot. I've barely scratched the surface with the few commands listed here. However, to use a lot of these, you need to have the Management Scripting Tools installed for IIS.

In some cases, depending on the version of the OS and PS, you may need to import the Web-Admin module prior to running other commands:
Import-Module WebAdministration

Export a List of Sites

Using Powershell Remotely

One can use PS remotely much like one can SSH into a Linux system and run commands as though they were local to the machine. Like with most things, you need to have all the correct permissions and settings for this to work.

PSRemoting

To get this to work, you need to enable PSRemoting. This is done on the server/host machine. It can be done a multitude of ways but we'll go into the manual method here.

On the Server/Host

With Linux, you need to allow remote access. Well, it's the same with Windows. Luckily, one or two commands will normally allow the access you need. First, the network category needs to be set to DomainAuthenticated or Private; if it's set to Public, this won't work. So, check that first and set it as needed. Obviously, these commands require an elevated prompt.

On the Client

Once your server/host is set correctly, you should be able to connect to it from a remote client so long as your network allows the traffic.

Example

Once connected via a remote session, you can run most commands you'd run from the console if you were sitting in front of it. Some won't work and you'll see a message on the screen if you try to run those.

Invoking a Remote Command

Once PSRemoting has been enabled, you can also invoke various commands without entering a PSSession. There's another site that has a lot of examples as well.

Example Scripts

Regex and Powershell

I'm no expert with Regular Expressions (Regex) but I've found it to be useful on many occasions. I've used it for manipulating text in Notepad++ but, now and then, you find yourself using it in various scripts. Here are some examples that I've used over the years.

Seeking out IPs

I used to help manage a SmarterMail mail server. Our config would capture potential SPAM emails and drop them into a holding cell. We'd go through the folder daily and weed out the few messages that were accidentally flagged as SPAM. I wrote a script to handle it and it uses some RegEx

When the raw mail files (EML and HDR) would get flagged as SPAM, they'd get prefixed with the sender's egress IP. So, the message would go from something like My cat photos.eml and My cat photos.hdr to 64.206.246.226IP.My cat photos.eml and 64.206.246.226IP.My cat photos.hdr. To drop the messages back into the processing queue, we'd manually rename the files, stripping out the 64.206.246.226IP. piece of it, and move them into the proper folder. Doing this for hundreds of files a day is mind-numbing! My script below seeks out any file with said preceding text and moves it - renaming it on the fly.

The Script

Rename_SmartMail_Spam_files.ps1
# Useful for dealing with the SPAM spools on SmarterMail
 
$Source = "\\h2p-mail1\Smartermail\Spool\spam\hold2"
$Dest = "\\h2p-mail1\Smartermail\Spool"
 
Get-ChildItem $Source\* -Include "*.eml","*.hdr" |
    Foreach-Object { Move-Item $Source\$($_.Name) $Dest\$($_.Name -Replace '(\d{1,3}\.){3}(\d{1,3}IP)\.','') }

The Breakdown

I'll do my best to break this down. Note the use of the -Include parameter for Get-ChildItem is telling the code to only touch the following two file-types: EML and HDR.

Networking Tasks with Powershell

Getting the Info to Manage a Network Interface Controller (NIC)

The following commands will list certain info for your NICs. Some of the info is needed to make changes so some of these commands are generally used prior to managing your NICs.

Setting IP Addresses and DNS Server Addresses

Once you've used something similar to the commands above, you can use some of that info to make changes. Setting a static IP is one of those things you can do.

Bulk Changing of IP Info on Multiple Servers

This is something I was tasked with years ago. I had to make changes to NICs on hundreds of servers. I was not about to do it by hand so I wrote scripts to do it. The servers had multiple NICs configured so I had to make sure I was changing the correct NIC's config and that complicated matters a bit.

Setting the Connection Profile

When your PC connects to a network, via a cable or a wireless network, Windows tries to place the network in one of three categories. Certain settings are then tweaked based on these categories - Public, Private and DomainAuthenticated. For instance, if it's set as a Public network, the Windows Firewall blocks more traffic than it would had you selected a Private network. The Private network profile will allow for things like shared folder and printer access but, if the profile is set to DomainAuthenticated, certain ports that are used for remote admin work get opened. I've had to change this from time to time and, frankly, I forget where to make these changes in the GUI so I always fall back to PS.

Using the Connection Profile for Printer Installations

I've used Get-NetConnectionProfile in a logon script for installing printers. Basically, it would make sure the user was connected to the proper network before trying to install printers the network printers. So, if the user was at home, it wouldn't waste any time trying to make sure the printers were installed. Below is the script I used. Never mind the reasons why it was used; it's just another example of pulling info from a NIC and using it accordingly.

Add_Printers_Logon.ps1
<#
    This should work in Windows 10 & Server 2016.
    To use this script, create a shortcut in common startup (START > RUN > SHELL:COMMON STARTUP).
	The shortcut should call PS something like this:
		powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -NonInteractive -NoLogo -File "C:\Scripts\add_printers_logon.ps1"
#>
 
# I've added a sleep-timer to avoid a timing issue with getting the system and its networking up and running.
# This can be adjusted to suit your needs.
Start-Sleep -Seconds 15
 
# Testing for an active network connection.
$upTest = ( Get-NetConnectionProfile | Where-Object {$_.IPv4Connectivity -ne "NoTraffic"} )
 
# Print server.  Some prefer an IP or NetBIOS name here.
$PrintServer = "prntsrvr2.gvsd.org"
 
# If the active network connection is on the correct domain, the printer installations will begin.  
if ($upTest.NetworkCategory -eq "DomainAuthenticated" -and $upTest.Name -ieq "gvsd.org" ) {
    Add-Printer -ConnectionName "\\$PrintServer\Color402_q"
    Add-Printer -ConnectionName "\\$PrintServer\Copy Center B-W_Q"
    Add-Printer -ConnectionName "\\$PrintServer\Copy Center Color_Q"
    Add-Printer -ConnectionName "\\$PrintServer\Print_Q"
    } else { 
    exit }

Miscellaneous PS Commands

I don't particularly like having a miscellaneous section but I'd rather not create subsections for every little command or script I've ever used when they don't fit in with the rest of this wiki.

Restart or Shutdown a Computer

These are very simple commands but also very useful. In a properly configured domain environment, they're very useful for working with remote machines.

Rename a Computer

These commands can be used locally or, in a properly configured domain, you can use them remotely.

Join the Computer to the Domain

Remove the Computer from the Domain

Working with Features and Roles on a Server

With relative ease, one can use PS to manage Features & Roles. I last used many of these on Server 2012-R2.

List Features and Roles on a Server

Install Features and Roles on a Server

One can use PS to do one-at-a-time installs or one could write a PS script to handle it. Generally speaking, if you're just installing a small number of packages at a time, Server 2012-R2 is smart enough to tell you when a package installation can't complete due to a dependency.

Uninstall Features and Roles on a Server

Like with the installations, one can use PS to do one-at-a-time uninstalls or one could write a PS script to handle it.

Uninstalling the package will do just that - uninstall it. If you wish to remove the payload - changing the InstallState flag to Removed - you can do that too. Doing so will clear up more space but, if you ever want to reinstall it, you'll need to supply the source files. In most cases, I prefer not to remove the payload due to the issues one has when trying to supply source files on a server which has a patch-level significantly higher than that of the source files.

Useless Fun with PS

Mask an Email Address

I had seen an example of this in a signature out on a forum. It took some digging but I got it working.

If your smallest number was something like 30, and you subtracted 22 from it, you'd end up with 8 - a 1-digit number. So, be mindful of your math and make sure you don't break the uniformity you're looking for.
1)
Remote machines take a little more work.
2)
true or false