wright_ps4_powershell_logo

Server Administration with PowerShell 4

TL;DR: PowerShell 4 is awesome, if you are a Windows Technician, Admin, Engineer, Architect, etc. you should be using it.

Intro

In 2007 Microsoft released PowerShell and since then the tool has grown to become one of the most, if not the most, powerful windows administration tool available for Microsoft operating systems and applications. Not only has Microsoft embraced PowerShell as the primary administration tool, but they have opened the door for vendors to develop modules to manage their own software and products. For example, we use Cisco PowerTool for managing their Unified Computing System (UCS) Platform and we utilize VMware PowerCLI for managing ESXi, vSphere, vCloud Director, and several other services and applications. PowerShell isn’t only for administrative purposes but also for personal use, you can even download a module for managing your Facebook account.

PowerShell provides cmdlets rather than command line executables. Cmdlets are instances of .NET framework classes that can perform CRUD actions on .NET framework objects. PowerShell’s runtime environment allows us to pipe results of cmdlets (.NET objects) to other cmdlets, providing a fluid way of administrating Microsoft Windows and applications. This post will focus on cmdlets that will streamline the administration of your server infrastructure.

Server Administration Cmdlets

Let’s geek out a little bit on some new cmdlets that have changed the way I work in regards to administrating a local server.

Add and Remove Windows Features

In legacy versions of windows, administrator’s hands were forced to use Server Manager or Control Panel to see what was installed or to install/uninstall window’s components. Starting with Server 2008 R2 the ServerManager module was introduced and it has never been easier to see what is installed, install additional features, uninstall features, and optionally remove them permanently.

Get-WindowsFeature – Gets information about Windows Server roles, role services, and features that are available for installation and/or are installed on a specified server. A few of the properties that we can filter these features by are DisplayName, InstallState, and Name. For example, in the following command we see what DHCP components are installed:

Get-WindowsFeature | Where Displayname -Match dhcp

            

Display Name                  Name      Install State

————                  —-      ————-

[ ] DHCP Server               DHCP          Available

        [X] DHCP Server Tools RSAT-DHCP     Installed

        

Install-WindowsFeature – This cmdlet installs one or more Windows Server roles, role services, or features on either the local or a specified remote server that is running Windows Server 2012 R2. This cmdlet replaces Add-WindowsFeature in previous versions. Here is how we can install all web server components on the local server:

Get-WindowsFeature Web* | Install-WindowsFeature

Success Restart Needed Exit Code      Feature Result

——- ————– ———      ————–

True    No             Success        {Remote Access, Application Initialization…

        

Uninstall-WindowsFeature – Uninstalls and optionally removes specified roles, role services, and features. We can use this cmdlet to actually get space back from the storage footprint of an installation of Windows. This cmdlet replaces Remove-WindowsFeature in previous versions. Let’s say we know we are never going to use SNMP, and you don’t want the additional installation files taking up space on your disk partition, you can remove it from the operating system to reclaim space:

Get-WindowsFeature *SNMP* | Uninstall-WindowsFeature -Remove -Confirm:$False

Success Restart Needed Exit Code      Feature Result

——- ————– ———      ————–

True    Yes            SuccessRest… {SNMP Tools, SNMP Service, SNMP WMI Provider}

WARNING: You must restart this server to finish the removal process.

        

Firewall Rules Administration

PowerShell 4, limited to Server 2012 or newer, introduces some game changers for managing host firewalls. The legacy command netsh advfirewall firewall was not only hard to remember, but very hard to automate firewall configuration. Let’s take a look at how we used to show all rules:

netsh advfirewall firewall show rule name=all

Once the rule name was found, we could modify it using even more complex syntax. Here is an example of how to change the remote addresses for WMI:

netsh advfirewall firewall set rule name=”Windows Management Instrumentation (WMI-In)” `

dir=in new remoteip=”192.168.1.0/24″

Remembering the syntax was difficult and if you wanted to do this from an object oriented perspective, you would need to use COM objects. This is how you could get a rule through COM:

$Rule = ((New-Object -ComObject HNetCfg.FwPolicy2).Rules) | `

Where-Object { $_.Name -eq “Windows Management Instrumentation (WMI-In)” }

This is how to change the remote IPs using COM:

$Rule.RemoteAddresses = “10.0.0.0/24”

This was easier, but remembering New-Object -ComObject HNetCfg.FwPolicy2 was still too complicated unless your primary job was firewall administration. To be honest, this resulted in me using the graphical Windows Firewall with Advanced Security Console the majority of the time. The only time I used PowerShell to adjust host firewalls was when I was forced to for scripting purposes. Starting with Server 2012 we have new cmdlets for host firewall administration which are included in the NetSecurity module:

Get-NetFirewallRule – Retrieves firewall rules from the target computer or server. This cmdlet allows the retrieval of all firewall rules or filtering by common things such as DisplayName, DisplayGroup, Enabled, and Action. The following snippet obtains information for WMI firewall rules, by grabbing all rules in the group:

Get-NetFirewallRule | Where DisplayGroup -Match “Windows Management Instrumentation” | `

select DisplayName,Name,Enabled,Action | Format-Table -AutoSize

DisplayName                                   Name                Enabled Action

———–                                   —-                ——- ——

Windows Management Instrumentation (DCOM-In)  WMI-RPCSS-In-TCP      False  Allow

Windows Management Instrumentation (WMI-In)   WMI-WINMGMT-In-TCP    False  Allow

Windows Management Instrumentation (WMI-Out)  WMI-WINMGMT-Out-TCP   False  Allow

Windows Management Instrumentation (ASync-In) WMI-ASYNC-In-TCP      False  Allow

Enable-NetFirewallRule – enables a previously disabled firewall rule to be enabled. Common parameters used by this cmdlet are a DisplayName, DisplayGroup, and Direction. These can be explicitly defined as a parameter of the cmdlet. This is how to enable a single rule:

Enable-NetFirewallRule -DisplayName “File and Printer Sharing (SMB-In)”

However, very often it is necessary to open up firewalls for purposes rather than single rules, for example enabling all WMI rules:

Enable-NetFirewallRule -DisplayGroup “Windows Management Instrumentation (WMI)” -PassThru | `

Select DisplayName,Enabled | ft -auto

DisplayName                                   Enabled

———–                                   ——-

Windows Management Instrumentation (WMI-In)      True

Windows Management Instrumentation (WMI-Out)     True

Windows Management Instrumentation (DCOM-In)     True

Windows Management Instrumentation (ASync-In)    True

The counteraction of this cmdlet is Disable-NetFirewallRule, which disables a previously enabled firewall rule.

Set-NetFirewallRule – modifies existing firewall rule properties. Common parameters used by this cmdlet are DisplayName and DisplayGroup. This is how to set the remote IP range able to access your host for File and Printer Sharing purposes:

Set-NetFirewallRule -DisplayGroup “File and Printer Sharing” -RemoteAddress 192.168.1.0/24

Get-NetFirewallRule -DisplayGroup “File and Printer Sharing” | `

Get-NetFirewallAddressFilter | Select RemoteAddress

RemoteAddress

————-

192.168.1.0/255.255.255.0

192.168.1.0/255.255.255.0

192.168.1.0/255.255.255.0

New-NetFirewallRule – Creates a new firewall rule. Common parameters used by this cmdlet are a DisplayName, Direction, Action, Protocol, and LocalPort. This is how to create a new firewall rule that requires a specific port to be open on the host:

New-NetFirewallRule -DisplayName “My Application” -Direction Inbound `

-Action Allow -EdgeTraversalPolicy Allow -Protocol TCP -LocalPort 28002 -RemoteAddress 192.168.1.0/24

Name                  : {487aedbf-0a0b-4965-baee-ec5a09024c73}

DisplayName           : My Application

Description           :

DisplayGroup          :

Group                 :

Enabled               : True

Profile               : Any

Platform              : {}

Direction             : Inbound

Action                : Allow

EdgeTraversalPolicy   : Allow

LooseSourceMapping    : False

LocalOnlyMapping      : False

Owner                 :

PrimaryStatus         : OK

Status                : The rule was parsed successfully from the store. (65536)

EnforcementStatus     : NotApplicable

PolicyStoreSource     : PersistentStore

PolicyStoreSourceType : Local

The counteraction of this cmdlet is Remove-NetFirewallRule.

Testing Network Connectivity

Troubleshooting network connectivity is a common task for administrators that is often more difficult than it has to be due to the poor tools available. Have you ever tried scripting out ping responses, telnet connections, or net view commands? Scripting out results of legacy tools was extremely hard and unreliable. Starting in Server 2012 R2 and Windows 8.1 there is a new cmdlet available that combines troubleshooting TCP connections, tracert, and ping and this cmdlet is part of the NetTCPIP module:

Test-NetConnection – cmdlet for testing network connectivity and common parameters include Port, Traceroute, and InformationLevel. Here is a very simple way to document which Active Directory computers have SMB enabled:

$smb = @{}

ForEach ($computer in Get-ADComputer -Filter *){

$test = Test-NetConnection -Computername $computer.DNSHostName -Port 445

$smb.Add($computer.DNSHostName, $test.TcpTestSucceeded)

}

$smb.count

30

Testing Web Sites and Web Requests

In PowerShell’s infancy, Windows admins had the hardest time trying to mimic common web tools such as wget on the Linux side. In the past I’ve scripted out starting IE through a COM object and attempting to script web requests. There are new cmdlets that save us significant amounts of time when we have to test HTTP responses from a variety of systems:

Invoke-WebRequest – sends HTTP and HTTPS requests to a web page or web service. It parses the response and returns collections of forms, links, images, and other significant HTML elements. Here’s a quick example of how we can test all of our sites using a CSV file as a data source, and store the results in a hash table:

$status = @{}

$sites = Import-Csv .\Hosted_Sites.csv

ForEach ($site in $sites){

    try {

        $result = (Invoke-WebRequest -Uri $site.Site).StatusCode

    }

    catch {

        $result = $_.ToString()

    }

    $status.Add($site.Site, $result)

}

Invoke-RestMethod – sends HTTP and HTTPS requests to Representational State Transfer (REST) web services that returns richly structured data. Windows PowerShell formats the response based to the data type. For an RSS or ATOM feed, Windows PowerShell returns the Item or Entry XML nodes. For JavaScript Object Notation (JSON) or XML, Windows PowerShell converts (or deserializes) the content into objects. With REST being a common web standard, this cmdlet expands the possibilities of PowerShell. We use Invoke-RestMethod to test our service APIs, but here is a quick example of using it to pull some map data from google map APIs:

Invoke-RestMethod -Uri “http://maps.googleapis.com/maps/api/geocode/xml?address=130+W+2nd+St+45402&sensor=false” -Method GET

Scheduled Jobs

PowerShell 4 introduces some improvements to some commands that have existed in previous versions. A great example of this is working with Scheduled Jobs (Scheduled Tasks). The legacy command line utility schtasks.exe was next to impossible to script and automate your work. Here is how we used to create a scheduled task:

schtasks /create /tn Update-File /tr ‘cmd /c ipconfig > c:\ip.txt’ /sc minute

A major problem is that you always have to identify a program that you want to run. Getting PowerShell to run as the program and execute a script was more difficult than it should have been. Now, we have PowerShell Scheduled Jobs, allowing us to utilize the .NET framework cmdlets to create and manage jobs:

Register-ScheduledJob – cmdlet for managing scheduled jobs on the local computer. A “scheduled job” is a Windows PowerShell background job that can be started automatically on a one-time or recurring schedule. Scheduled jobs are stored on disk and registered in Task Scheduler, so they can be managed in Task Scheduler or PowerShell. Here is an example of how to create a scheduled job to send an email every minute:

$minute = New-TimeSpan -Minute 1

$trigger = New-JobTrigger -Once -At 12am -RepetitionInterval $minute `

-RepeatIndefinitely

Register-ScheduledJob -Name “Send Email” -Trigger $Trigger -ScriptBlock {

    Send-MailMessage -SmtpServer localhost -To [email protected] -From [email protected] `

    -Subject “Minute Notice” -Body “Testing every minute emails!”

}

 

Conclusion

In 2009 I wrote the following in a blog post, “For those Windows Admins that haven’t tampered with Windows PowerShell I recommend you start… I am finding the more I dive in the less I want to come up for air.” The same holds true today and 3 PowerShell versions later. PowerShell is only becoming more powerful as time goes on, and DataYard is taking advantage on the ability to automate administrative tasks and make our jobs easier. Here are some quick PowerShell resources that will help you, no matter your familiarity with PowerShell:

Stay tuned for future posts about PowerShell!

Recommended Posts