Wednesday 13 January 2016

PowerShell: List all IPv4 Addresses

A very short blog post today. I'm not sure why this is so complicated, maybe there's an easier way, or a more recent cmdlet that allows it to be obtained in an easier way.

I want to list all IP (v4) addresses and nothing else with a single line PowerShell command that is backwards compatible with all versions of PowerShell.

Here's what I came up with:

foreach ( $i in (Get-WmiObject Win32_NetworkAdapterConfiguration -Namespace "root\CIMV2" | where { $_.IPEnabled -eq "True" } | select IPAddress) ) { $i.IPAddress[0] }

Here's a quick breakdown of the command

It's basic structure uses a foreach loop

Foreach ( $TempVariable in $MyVariableList ) { do this }

$i is my temporary variable, that exists only for the purposes of the loop. The Foreach loop will cycle through each object in the second variable, and each time it will be represented by $i

$MyVariableList is a variable that contains many objects, and is often obtained in a script by a separate command. As I want a one-liner, I have substituted this variable with a command that produces a list of objects.

This is my command:

Get-WmiObject Win32_NetworkAdapterConfiguration -Namespace "root\CIMV2" | where { $_.IPEnabled -eq "True" } | select IPAddress)

It uses Get-WMIObject to return the WMI class Win32_NetworkAdapterConfiguration. I chose the Get-WMIObject command to return the IP address data because I know it is compatible with all version of PowerShell. This command on its own returns a large amount of data, so I have piped the results to the Where-Object command. This filters to return only network adapters that are enabled. These results are then piped to the Select-Object command, and this selects the single property of IP address.


IP Address properties






The result is an IP address object for each adapter. Each contains both an IPv4 and IPv6 address.

{ do this } Finally the Foreach loop will carry out an action on each object that is returned. In this case it simply takes the object and calls the IPAddress property (which is the only one available). The square brackets specify the 1st result only will be displayed.

IP Address list




Simple.




Wednesday 6 January 2016

Scripting IIS App Pools (v8.5) with PowerShell



App Pools

It's quite common to automate the process for creating a web site and its associated application pools. Creating an app pool is a simple process, but the many different settings that can be used is where things can get complicated. In my experience I found that PowerShell's Set-ItemProperty can get complicated when it's used with IIS app pools, so here's a few things I found out.

The IIS:\ provider doesn't work unless the WebAdministration module is first imported. So the following command must be run at the beginning of any script

Import-Module WebAdministration or ipmo webadministration

To fetch a list of app pools, run

Get-Item IIS:\AppPools\*


Whenever I'm working with something for the first time, I select one object, then pass it to the Format-List cmdlet which enables me to see every available property.

Get-Item IIS:\AppPools\* | select-object -First 1 | Format-List -Property * 


This displays all the properties that were hidden from the results of the first Get-Item command. I could also select a specific app pool

Get-Item IIS:\AppPools\MyAppPool | Format-List -Property *

I can see several results display Microsoft.IIs.PowerShell.Framework.ConfigurationElement rather than an actual value.

App Pool properties


 


This is where we need to switch to the Get-ItemProperty cmdlet to see the property details in full.

Get-Item IIS:\AppPools\* | select-object -First 1 | Get-ItemProperty -name processmodel

or for a specific App Pool

Get-Item IIS:\AppPools\MyAppPool | Get-ItemProperty -name processmodel
this can also be written as

(Get-ItemProperty IIS:\AppPools\MyAppPool).processmodel
or

Get-ItemProperty IIS:\AppPools\MyAppPool -name processmodel
The results show that processmodel has several properties.

processModel properties









I expected to be able to change one of these properties by running a command like this

Set-ItemProperty IIS:\AppPools\MyAppPool -name processmodel.identitytype -Value ApplicationPoolIdentity

When I run this command, it executes without an error, but no changes are made.

Similarly with other App Pool settings the Set-ItemProperty command does not make changes.

Set-ItemProperty IIS:\AppPools\MyAppPool -name managedPipeLineMode -value Integrated

After some experimentation I found that the name parameter of Set-ItemProperty is case sensitive

When I go back and examine my previous commands, I can see that processmodel is in fact processModel, and identitytype is identityType. Also I should've been using managedPiplineMode.

Once I change my commands accordingly, the Set-ItemProperty command correctly makes the changes.

Set-ItemProperty IIS:\AppPools\MyAppPool -name processModel.identityType -Value ApplicationPoolIdentity

Set-ItemProperty IIS:\AppPools\MyAppPool -name managedPipelineMode -value Integrated