Emergency Maintenance Window 02/17/2016

On Wednesday February 17th at 10:00 PM EST, the DataYard Technical Operations Team performed critical software updates on our managed linux environments.  More information on the bug can be found here:

https://www.debian.org/security/2016/dsa-3481

If you have any questions regarding this maintenance please contact our technical support team at 1.800.982.4539 or support@datayard.us. Remember to follow us on Twitter (@datayardtechops) for the latest service and maintenance status updates at DataYard.

SAN Upgrade 02/09/2016

We are performing a SAN upgrade on 02/09/2016.  We expect a minimal outage (<5 minute outage) for the following services:

  • Windows Fusion (IIS Hosting)
  • Legacy Connect Email
  • Spam Processing Services
  • Legacy Linux Shared Hosting

As always, if you have any questions please let us know by calling 937-226-6896 or emailing support@datayard.us.

Remote Server Administration with PowerShell


Notice: Undefined index: extension in /var/www/vhosts/datayard.us/wp-content/themes/jupiterx/lib/api/image/class-image-editor.php on line 169

Notice: Undefined index: extension in /var/www/vhosts/datayard.us/wp-content/themes/jupiterx/lib/api/image/class-image-editor.php on line 169

Remote Server Administration with PowerShell

Your RDP Client is going to get straight up jealous

Intro

In the past remote Window’s administration has been limited to RDP, Citrix, DRAC/KVM, VNC, or the command line using PsExec. Developing scripts to remotely connect to hosts and gather data utilizing these legacy technologies became very cumbersome. One of the best things about PowerShell is the ability to manage hosts remotely quickly and efficiently. In a previous post I wrote about Local Server Administration with PowerShell which included quick glances at cmdlets for managing Windows features, firewall administration, network connectivity diagnostic tools, HTTP and HTTPS diagnostic cmdlets, and scheduled job management. The same cmdlets are available remotely; allowing us to configure servers without the need to RDP and executing PowerShell commands locally.

First we need to understand Windows Remote Management (WinRM) as PowerShell uses this technology to remotely connect to servers and other infrastructure. WinRM provides a common way for systems to access and exchange management information across an IT infrastructure. WinRM was introduced with the Windows Vista/Server 2008 kernel and can retroactively be installed in earlier versions by installing Windows Management Framework 2.0.

Security Implications with WinRM

Before implementing PowerShell Remoting it is important to understand the security implications. WinRM, by default, will use the HTTP protocol on port 5985 to communicate with a remote host. Microsoft Negotiate Authentication will decide to authenticate using either Kerberos and NTLM. The preference will be Kerberos, which will be used in the same AD domains or domains with trust relationships.

If you analyze packet captures during the WinRM process over HTTP, and follow the entire TCP stream, you will see that the content is encrypted with the content type of HTTP-SPNEGO-session-encrypted for NTLM v2 and HTTP-Kerberos-session-encrypted for Kerberos. Here is an example of a WinRM session using Kerberos as the local and remote computers were on the same domain:

WinRM-Kerberos-Capture

The actual password is never sent over the wire and the only way that a password could be decoded is if the Security Accounts Manager (SAM) on the remote machine had already been compromised. The hash that is stored in the Security Accounts Manager is never actually sent and cannot be decoded. Even if there was someone snooping packets on the network they wouldn’t see anything in clear text and therefore an exploit is extremely unlikely. With this data we conclude that WinRM is encrypted by default and that configuring WinRM for HTTPS would be an added layer of security.

Configuring PowerShell Remoting

Configuring PowerShell Remoting was originally difficult and time consuming because administrators had to manually create the WinRM listener, set the service to automatically start, enable PowerShell session configurations, and troubleshooting authentication. Now, all of this is configured out of the box; primarily because the majority of new management tools application require this to properly function. Additionally, several cmdlets have a ComputerName parameter that is supported to identify which computer you want to run the command on. Here is how you can enable PowerShell remoting on previous versions of Windows.

Configure PowerShell Remoting with HTTP

Starting in PowerShell 2.0 you can enable PowerShell remoting with a single command:

Enable-PSRemoting

The Enable-PSRemoting cmdlet runs the Set-WSManQuickConfig cmdlet, which performs the following tasks:

  • Starts the WinRM service.
  • Sets the startup type on the WinRM service to Automatic.
  • Creates a listener to accept requests on any IP address.
  • Enables a firewall exception for WS-Management communications.
  • Registers the Microsoft.PowerShell and Microsoft.PowerShell.Workflow session configurations, if it they are not already registered.
  • Registers the Microsoft.PowerShell32 session configuration on 64-bit computers, if it is not already registered.
  • Enables all session configurations.
  • Changes the security descriptor of all session configurations to allow remote access.
  • Restarts the WinRM service to make the preceding changes effective.

Configuring PowerShell Remoting with HTTPS

If you would like this additional layer of security, the process is slightly more complex than the Enable-PSRemoting command. The first thing you need to do is obtain an SSL cert for the remote server or workstation. You can script out the issuing of certificates by using Certificate Enrollment Web Service and Certificate Enrollment Policy Web Service in Windows Server 2012 R2. I would also recommend deploying a duplicate of the Web Server certificate template and modifying the settings to meet your organization’s needs. Here is an example of how you can obtain these certificates using PowerShell.

PS C:\> $uri = “https://yourca.domain.tld/Policy/service.svc”

PS C:\> $fqdn = “remotehost.domain.tld”

PS C:\> $subject = “E=support@datayardworks.com, C=US, S=Ohio, L=Dayton, O=DataYard, OU=TechOps,CN=$fqdn”

PS C:\> $netbios = “remotehost”

PS C:\> $creds = Get-Credential

PS C:\> Get-Certificate -Template “WinRM” -Url $uri -DNSName $fqdn,$netbios -CertStoreLocation cert:\LocalMachine\My `

-SubjectName $fqdn `

-Credential $creds

You can issue these commands from the remote host in the same domain. If the certificate request is issued, then the returned certificate is installed in the machine’s personal certificate store. If the request is made pending, then the request is installed in the machine’s request store. Once you have the certificate installed you will need to obtain the certificate thumbprint for the issued certificate and copy it to your clipboard:

PS C:\> $thumbprint = (gci cert:\LocalMachine\My | Where {$_.Subject -eq $subject}).Thumbprint

PS C:\> $thumbprint | clip

In order to create the HTTPS WinRM listener you will have to use a command prompt and not PowerShell as you will receive an error “Error: Invalid use of command line. Type “winrm -?” for help”. In the following example we also delete the default HTTP listener:

C:\> winrm create winrm/config/Listener?Address=*+Transport=HTTPS  @{Hostname=”remotehost.domain.tld”;CertificateThumbprint=”E1ED1974E00A9789DFDD417A690F2C1480FD224A”}

C:\> winrm delete winrm/config/Listener?Address=*+Transport=HTTP

Now that WinRM is actively listening on 5986 we need to modify the firewall rules in PowerShell to reflect our changes. We strongly suggest restricting the remote addresses able to access this service for an additional layer of security:

PS C:\> Get-NetFirewallRule | Where {$_.Name -match “WINRM-HTTP-In-TCP”} | Disable-NetFirewallRule

PS C:\> New-NetFirewallRule -Name “WINRM-HTTPS-In-TCP” -DisplayName “Windows Remote Management (HTTPS-In)” `

-Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986 -RemoteAddress 10.0.0.0/24

Utilizing PowerShell Remoting

Now that we have PowerShell Remoting configured there are several options to remotely connect. These options include the ComputerName parameter, Invoke-Command, PSSession capabilities, and implicit remoting.

ComputerName Parameter

You can run commands on a remote computer by using the ComputerName parameter. Although many cmdlets now offer a ComputerName parameter, there are a limited number of cmdlets with this parameter available. When you use this parameter Windows PowerShell creates a temporary connection that is used for the command and is then closed. Here is an example regarding memory consumption on a remote host:

PS C:\> Get-Process -ComputerName remotehost.domain.tld | sort WorkingSet | select -last 5

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

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

   4658      93   100208     185996   669            3612 OUTLOOK

   1358     130   178744     214380   631           11912 VpxClient

   5917     104   136148     220148   772            5480 OUTLOOK

    463      32   268112     231492   780           10780 javaw

   7114     108   175692     269376   878            3528 OUTLOOK

Here are all of the commands with the ComputerName parameter available:

PS C:\> Get-Command | ForEach { if ($_.Parameters.Keys -Contains “ComputerName”){$_}} | select name

Name

—-

Add-Computer

Clear-EventLog

Connect-PSSession

Enter-PSSession

Get-EventLog

Get-HotFix

Get-Process

Get-PSSession

Get-Service

Get-WmiObject

Invoke-Command

Invoke-WmiMethod

Limit-EventLog

New-EventLog

New-PSSession

Receive-Job

Receive-PSSession

Register-WmiEvent

Remove-Computer

Remove-EventLog

Remove-PSSession

Remove-WmiObject

Rename-Computer

Restart-Computer

Set-Service

Set-WmiInstance

Show-EventLog

Stop-Computer

Test-Connection

Write-EventLog

I primarily utilize the ComputerName parameter for quickly identifying issues with servers in our local domain or dev environments. Since invoking a cmdlet only creates a temporary connection, any time you need to perform several action items on a remote host I would recommend to utilize PowerShell Sessions (PSSessions).

Invoke-Command

Invoke-Command is perhaps the most versatile way to remotely connect to hosts with PowerShell. You can use this command to execute scriptblocks locally, remotely, through a remote session with or without arguments, or through a connection endpoint URI. Invoke-command can also be used to invoke the same scriptblock on several different servers; we can also identify a filepath to predefined scripts to run remotely. You can also use Invoke-Command on a local computer to evaluate or run a string in a script block as a command. Windows PowerShell converts the script block to a command and runs the command immediately in the current scope, instead of just echoing the string at the command line.The Invoke-Command cmdlet runs commands on a local or remote computer and returns all output from the commands, including errors.

Here is an example of grabbing the configured DNS servers on all interfaces for several servers in your domain:

PS C:\> $server1 = “server1.domain.tld”

PS C:\> $server2 = “server2.domain.tld”

PS C:\> $server3 = “server3.domain.tld”

PS C:\> Invoke-Command -ScriptBlock { Get-DNSClientServerAddress } `

>> -ComputerName $server1,$server2,$server3

>>

InterfaceAlias               Interface Address ServerAddresses                                PSComputerName

                             Index     Family

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

Ethernet                            12 IPv4    {192.168.1.101, 192.168.1.102}                 server1.domain.tld

Ethernet                            12 IPv4    {192.168.1.101, 192.168.1.102}                 server2.domain.tld

Ethernet                            12 IPv4    {192.168.1.101, 192.168.1.102}                 server3.domain.tld

PSSession Capabilities

A PSSession is a persistent PowerShell Session on a local or remote computer. Use a PSSession to run multiple commands that share data, such as a function or the value of a variable. Commands are executed inside of a PSSession using the Invoke-Command. Through PowerShell session options and New-PSSession parameters we can connect to a remote machine to perform the vast majority of our actions, and we can develop very elaborate scripts by connecting to and storing persistent PowerShell sessions.

Invoke-Command and PSSessions

Let’s start with the basics of creating a new session, storing it in a variable, and then issuing a command:

PS C:\> $session = New-PSSession remotehost.domain.tld

PS C:\> Invoke-Command -Session $session -ScriptBlock { (Get-NetAdapter).Name }

vEthernet (Internal Ethernet Port Windows Phone Emulator Internal Switch)

vEthernet (Realtek PCIe GBE Family Controller – Virtual Switch)

Production Interface (95)

That is a very basic example of capturing data from a remote host. Here is a little bit more of an advanced example of how we can capture all IPs from a remote host, and create A records on our domain controller (a different remote host) for all the server IPs:

PS C:\> $creds = Get-Credential

PS C:\> $remote_fqdn = “remotehost.domain.tld”

PS C:\> $dc = “domaincontroller.domain.tld”

PS C:\> $session1 = New-PSSession $remote_fqdn -Credential $creds

PS C:\> $session2 = New-PSSession $dc -Credential $creds

PS C:\> $ips = Invoke-Command -Session $session1 -ScriptBlock {

(Get-NetIPAddress | Where {$_.InterfaceAlias -notmatch “Loopback”}).IPAddress

}

PS C:\> $ips

10.0.1.42

10.0.0.42

172.16.2.1

192.168.1.108

192.168.1.105

PS C:\> Invoke-Command -session $session2 -ArgumentList $remote_fqdn,$ips -scriptblock {

param ($remote_fqdn, $ips)

$name = $remote_fqdn.split(“.”)[0]

ForEach ($ip in $ips){

#Add-DnsServerResourceRecordA -ZoneName domain.tld. -Name $name -IPv4Address $ip

$ip

}

}

Enter-PSSession

Persistent PowerShell sessions are great for scripting purposes, but troubleshooting on the fly and utilizing Invoke-Command and ScriptBlocks is not a practical solution. However, with the Enter-PSSession command you can connect interactively to a PowerShell session on any properly configured remote system. The Enter-PSSession cmdlet starts an interactive session with a remote computer. During the session, the commands that you execute run on the remote computer, just as though you had a local PowerShell sesssion on it (one thing to note is that you can have only one interactive session at a time). Here is an example of connecting to a remote computer:

PS C:\> Enter-PSSession remotehost.domain.tld -Credential (Get-Credential)

In the past we had to launch an RDP client, enter in credentials, wait on the user profile and startup programs to load, and launch a PowerShell session. These actions took much longer than Enter-PSSession. The Enter-PSSession cmdlet is my personal favorite for PowerShell remoting because it is a subsitute for remote desktop and decreases the administrative time to connect to remote hosts.

Implicit Remoting

PowerShell remoting gets even better as you can take it one step further and create PowerShell modules from your PowerShell sessions you create. For example, I created modules for managing our corporate exchange servers (Exchange 2013):

PS C:\> $creds = Get-Credential

PS C:\> $uri = “https://exchange.domain.tld/PowerShell”

PS C:\> $exchange = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI $uri -Authentication Basic `

-Credential $creds -SessionOption (New-PSSessionOption -NoMachineProfile -SkipCACheck -SkipCNCheck -SkipRevocationCheck)

PS C:\> Export-PSSession -Session $exchange -CommandName * -OutputModule DataYardExchange -AllowClobber

Managing remote infrastructure becomes significantly easier as we build custom modules for our environment. Implicit remoting and PowerShell modules will not store your password(s) and will prompt you accordingly upon importing the module. Here is an example of modifying DataYard’s corporate exchange environment with the module we recently created:

PS C:\> Import-Module DataYardExchange

PS C:\> Set-Mailbox eric.wright -EmailAddresses @{add=”PowerShell@datayardworks.com”}

PS C:\> (Get-Mailbox eric.wright).EmailAddresses

smtp:PowerShell@datayardworks.com

smtp:eric.wright@datayardworks.com

Another way to take advantage of implicit remoting is by utilizing the cmdlet Import-PSSession. Rather than creating a module we can create a PSSession and then use the Import-PSSession cmdlet to implicitly remote to the server:

PS C:\> $creds = Get-Credential

PS C:\> $uri = “https://exchange.domain.tld/PowerShell”

PS C:\> $exchange = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI $uri -Authentication Basic `

-Credential $creds -SessionOption (New-PSSessionOption -NoMachineProfile -SkipCACheck -SkipCNCheck -SkipRevocationCheck)

PS C:\> Import-PSSession $exchange

PowerShell Web Access

The last feature to discuss is PowerShell Web Access (WindowsPowerShellWebAccess). This allows you to execute PowerShell commands through an encrypted website from any web browser. PowerShell Web Access can be configured using the following commands:

PS C:\> Install-WindowsFeature -Name WindowsPowerShellWebAccess -IncludeManagementTools

PS C:\> Install-PswaWebApplication -webApplicationName pswa -UseTestCertificate

PS C:\> Add-PswaAuthorizationRule -UserName domain\user -ComputerName localhost -ConfigurationName Microsoft.PowerShell

PS C:\> start iexplore.exe https://localhost/pswa

In your favorite web browser (Chrome, Firefox, Safari, or IE) you can utilize PowerShell Web Access from anywhere in the world. This is a screenshot of PowerShell Web Access from Safari on an iPhone:

 IMG_6112

I strongly suggest to implement additional layers of security by restricting the IP space that is able to access this feature as well as utilizing additional authentication schemes such as Windows Authentication, Basic Authentication, and/or client certificate verification at the IIS level.

Conclusion

There are many ways to connect to and manage remote systems, PowerShell becoming the most consistent way to manage Window’s infrastructure. As you can see the functionality of persistent PSSessions and modules can become very elaborate. Remote management techniques for Windows’ infrastructure has been constantly improving and I look forward to the incremental improvements.

Windows Fusion 2.0 – 6/13/2014


Notice: Undefined index: extension in /var/www/vhosts/datayard.us/wp-content/themes/jupiterx/lib/api/image/class-image-editor.php on line 169

Notice: Undefined index: extension in /var/www/vhosts/datayard.us/wp-content/themes/jupiterx/lib/api/image/class-image-editor.php on line 169

DataYard system’s engineers have recently completed a new web cluster based on Server 2012 R2 and IIS 8.5. The cutover from our existing cluster to the new cluster will not require customer interaction and sites should not incur any downtime. We will be changing DNS records for all sites on 6/13/2014 at 5 PM. Please contact us by calling 937-226-6896 or emailing support@datayardworks.com if you have any questions or concerns. 

Server Administration with PowerShell 4.0

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 test@localhost.com -From test@localhost.com `

    -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!