PowerShell for Windows Admins


August 22, 2011  3:05 PM

TechEd Australia PowerShell conference

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tuesday August 30th 2011 at 9am EST there is a PowerShell conference at TechEd Australia. 

Details from

http://powershelldownunder.com/featured/teched2011/

The sessions will be available via Live meeting please register at above URL

August 22, 2011  1:03 PM

Ping a subnet

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I recently needed to find which IP addresses were active on a subnet to track down a printer. Quickest way was to ping them.

 

function ping-subnet {            
param (            
 [parameter(Mandatory=$true)]            
 [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\b")]            
 [string]$subnet            
)            
            
0..255 | foreach {             
             
 $address = "$subnet.$_"            
            
 if (Test-Connection -ComputerName $address -Count 1 -Quiet){            
    Test-Connection -ComputerName $address -Count 1            
 }            
            
}            
}

 

Put the subnet in as a parameter. Then work through 0 – 255 building an address from the subnet. use test-connection in quiet mode and if it responds do a 1 count test-connection (ping) to get the result.

Not necessarily the quickest but it was quick to throw together and it works


August 21, 2011  12:24 PM

Create a process on a remote machine

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We can use the [wmiclass] to create a process but it doesn’t allow us to set the credentials. We can get round that by using a bit of .NET code. [wmiclass] is as accelerator for System.Management.ManagementClass so we go back to basics

function new-process {            
param (            
 [string]$computer="localhost",            
 [string]$procpath="C:\Program Files\Internet Explorer\iexplore.exe"            
)            
            
$conopt = New-Object System.Management.ConnectionOptions             
            
switch ($computer ) {            
 "."         {break}            
 "localhost" {break}            
 "$env:COMPUTERNAME" {break}            
 default {            
           $cred = Get-Credential            
           $conopt.UserName = $cred.UserName            
           $conopt.SecurePassword = $cred.Password            
         }            
}            
$conopt.EnablePrivileges = $true            
            
$scope = New-Object System.Management.ManagementScope             
$scope.Path = "\\$computer\root\cimv2"             
$scope.Options = $conopt             
            
$path = New-Object System.Management.ManagementPath            
$path.ClassName = "Win32_Process"              
            
$proc = New-Object System.Management.ManagementClass($scope, $path, $null)             
            
$proc.Create($procpath)             
}

 

The computer name and path to the exe we want to run are given as parameters. We create the System.Management.ConnectionOptions. If we are  targeting a remote machine we can add the credentials (doesn’t work for local machine). The switch simplifies the coding of avoid local machine

 

The scope and management path (name space and class) are set and then we create a new instance of the class. We can then use the Create method to create the process.


August 21, 2011  11:01 AM

Ethernet Errors

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

While we are looking at the MSNdis_Ethernet* classes we should consider these three that pick up potential problems

MSNdis_EthernetReceiveErrorAlignment
MSNdis_EthernetOneTransmitCollision
MSNdis_EthernetMoreTransmitCollisions

 

If all is well we will get an answer of zero for each of them – no errors and no collisions. Its a bit awkward working through each class in turn and we get a lot of “noise” returned so the following function concatenates the results.

function test-etherneterror {            
param(            
 [string]$computer="."            
)            
Get-WmiObject -Namespace root\wmi -Class MSNdis_EthernetReceiveErrorAlignment `
-ComputerName $computer |            
foreach {            
                
  $one = Get-WmiObject -Namespace root\wmi  `
  -Class MSNdis_EthernetOneTransmitCollision -ComputerName $computer `
  -Filter "InstanceName='$($_.InstanceName)'"            
            
  $more = Get-WmiObject -Namespace root\wmi  `
  -Class MSNdis_EthernetMoreTransmitCollisions -ComputerName $computer `
  -Filter "InstanceName='$($_.InstanceName)'"            
            
  New-Object -TypeName PSobject -Property @{            
  Computer = $_.__SERVER            
  Adapter = $_.InstanceName            
  ReceiveError = $_.NdisEthernetReceiveErrorAlignment            
  OneCollision = $one.NdisEthernetOneTransmitCollision            
  MoreCollision = $more.NdisEthernetMoreTransmitCollisions            
 }            
}            
}

Start by getting the members of the MSNdis_EthernetReceiveErrorAlignment  class. Loop through them and get the related MSNdis_EthernetOneTransmitCollision  and MSNdis_EthernetMoreTransmitCollisions classes.

 

Create an object for output


August 20, 2011  12:29 PM

Powershell and WMI–MEAP Chapters 12 and 13

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Chapters 12 and 13 have been added to the early access program.

 

Chapter 12: Internet Information Server (IIS) may not be the first application that comes to mind when we think of using WMI to administer remote servers, but it provides a lot of functionality. You’ll learn to administer the web server itself, websites, applications, and application pools.

Chapter 13: Configuring a new server is a task that occurs on a regular basis in most organizations. All of the activities required to configure a new server take time. You can use PowerShell functions to perform these tasks remotely so you don’t need to spend time accessing the server directly.

The code for all chapters is available for download.

 

The MEAP is available from http://www.manning.com/siddaway2/


August 19, 2011  1:10 PM

Testing MAC address changes

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

My recent post on using MSNdis_EthernetCurrentAddress to get the MAC address may have had you saying so what because I can do this

 

Get-WmiObject -Class Win32_NetworkAdapter -ComputerName "." | select Name, MACAddress

 

However, there is another class MSNdis_EthernetPermanentAddress which shows the permanent address. This means we can see if the MAC address has been changed. This does happen in a few places including NLB.

function convert-macaddresstostring{            
 param ($address)            
             
 $values = @()            
 $address |             
 select -ExpandProperty Address |            
 foreach {            
  $values += ([convert]::ToString($_,16)).ToUpper().PadLeft(2,"0")            
 }            
             
 $values -join "-"            
}             
            
function test-macaddresschange {            
param(            
 [string]$computer="."            
)            
Get-WmiObject -Namespace root\wmi -Class MSNdis_EthernetCurrentAddress `
-ComputerName $computer |            
foreach {            
              
  $currentmac = convert-macaddresstostring $($_.NdisCurrentAddress)            
              
  $perm = Get-WmiObject -Namespace root\wmi  `
  -Class MSNdis_EthernetPermanentAddress -ComputerName $computer `
  -Filter "InstanceName='$($_.InstanceName)'"            
              
  $permanentmac = convert-macaddresstostring $($perm.NdisPermanentAddress)            
              
  New-Object -TypeName PSobject -Property @{            
  Computer = $_.__SERVER            
  Adapter = $_.InstanceName            
  CurrentMACAddress = $currentmac            
  PermanentMACAddress = $permanentmac            
 }            
}            
}            
            

You should recognise this from the previous post. We use MSNdis_EthernetCurrentAddress  and loop through the adapters. Then MSNdis_EthernetPermanentAddress  is used to get the permanent MAC address of the instance. Instance name is used as a filter. The conversion of the MAC address from integer array to string is pushed into its own function.

The output object is altered to show current and permanent addresses


August 18, 2011  1:01 PM

Find the MAC address

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One thing that has bugged me for years is having to use the /all parameter with ipconfig to get the MAC address. It also doesn’t work on remote machines. bah humbug.

The MSNdis_EthernetCurrentAddress class in the root\wmi namespace offers a quicker way

function get-macaddress {            
param(            
 [string]$computer="."            
)            
Get-WmiObject -Namespace root\wmi -Class MSNdis_EthernetCurrentAddress `
-ComputerName $computer |            
foreach {            
 $values = @()            
 $_.NdisCurrentAddress |             
 select -ExpandProperty Address |            
 foreach {            
  $values += ([convert]::ToString($_,16)).ToUpper().PadLeft(2,"0")            
 }            
             
 $mac = $values -join "-"            
 New-Object -TypeName PSobject -Property @{            
  Computer = $_.__SERVER            
  Adapter = $_.InstanceName            
  MACAddress = $mac            
 }            
}            
}

Get the WMI objects for MSNdis_EthernetCurrentAddress. For each of them take the NdisCurrentAddress and expand the address property. This gives 6 integer values one for each element of the MAC address. We convert them to hex, convert to upper case and pad a 0 to the left if needed. the MAC address is created by joining those 6 values with a hyphen.

An object is created to output the results


August 17, 2011  2:19 AM

Half price PowerShell books

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Check www.manning .com for a half price deal on PoweShell books:

  • PowerShell in Practice
  • PowerShell and WMI
  • PowerShell in Action
  • Learn PowerShell in a month of lunches

Hurry. Today only!


August 9, 2011  12:58 PM

Book review: SQL Server DMVs in Action

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Title: SQL Server DMVs in Action

Author: Ian Stirk

Publisher: Manning

ISBN: 978-1-935182-73-3

 

DMVs are Dynamic Management Views – they were introduced in SQL Server 2005 and further refined in SQL Server 2008. They maintain information about whats happening on on your SQL Server – in real time. They supply a snapshot of whats happening and a view of what has happened as they accumulate data since SQL Server was started.

DMVs are a very powerful, but little understood facet of SQL Server.  The book has 11 chapters:

  1. The DMV gold mine
  2. Common patterns
  3. Index DMVs
  4. Improving poor query performance
  5. Further query improvements
  6. Operating System DMVs
  7. Common Language RunTime DMvs
  8. Resolving Transaction issues
  9. Database level DMVs
  10. The self-healing database
  11. Useful scripts

At 325 pages its not a massive book but it is packed with useful information. The first two chapters supply an overview of DMVs and some common code patterns that will be re-used throughout the book. The second chapter will repay careful reading as the themes introduced here permeate the whole book.

The books second part – chapters 3-11 – cover how to use DMVs to solve database related problems. The chapter titles speak for themselves with chapter 3 showing ways to identify missing indexes and 4 and 5 showing how to identify and improve SQL queries

Chapter 6 covers SQL Server’s interaction with the OS and the server – showing how to identify waits and blocks. Chapter 7 on the CLR is of great interest if you are using CLR code in your queries. Chapters 8 and 9 on transactions and databases are back to finding SQL Server related issues.. The last two chapters show how to pull all of this together to produce a database that can start to heal its own problems – personally I’d prefer it to make suggestions rather than implement but that is just details. The final chapter presents some useful scripts that build on the earlier chapters.

The books 100+ code snippets are ready to use and directly useful in your environment

If you work with SQL Server this is one you should have on your book case.  Highly recommended


August 7, 2011  10:05 AM

MSDiskDriver_Performance

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We have looked at the MSDiskDriver_Geometry  class now lets look at the MSDiskDriver_Performance class

This is a bit more complicated because the Perfdata property is actually an instance of the MSDiskDriver_PerformanceData class

function get-msdiskdriverperfomance  {            
[CmdletBinding()]            
param (            
 [string]$computer="."            
)            
            
PROCESS{            
$date = Get-Date -Format F            
Get-WmiObject -Namespace root\wmi -Class msdiskdriver_performance `
-ComputerName $computer |             
foreach {            
 $perfdata =  $_ | select InstanceName, Active, DeviceName             
 $perfdata |            
 Add-Member -MemberType NoteProperty -Name TimeStamp -Value $($date) -PassThru |            
 Add-Member -MemberType NoteProperty -Name BytesRead -Value $($_.PerfData.BytesRead) -PassThru |            
 Add-Member -MemberType NoteProperty -Name BytesWritten -Value $($_.PerfData.BytesWritten) -PassThru |            
 Add-Member -MemberType NoteProperty -Name IdleTime -Value $($_.PerfData.IdleTime) -PassThru |            
 Add-Member -MemberType NoteProperty -Name QueryTime -Value $($_.PerfData.QueryTime) -PassThru |            
 Add-Member -MemberType NoteProperty -Name QueueDepth -Value $($_.PerfData.QueueDepth) -PassThru |            
 Add-Member -MemberType NoteProperty -Name ReadCount -Value $($_.PerfData.ReadCount) -PassThru |            
 Add-Member -MemberType NoteProperty -Name ReadTime -Value $($_.PerfData.ReadTime) -PassThru |            
 Add-Member -MemberType NoteProperty -Name SplitCount -Value $($_.PerfData.SplitCount) -PassThru |            
 Add-Member -MemberType NoteProperty -Name StorageDeviceNumber -Value $($_.PerfData.StorageDeviceNumber) -PassThru |            
 Add-Member -MemberType NoteProperty -Name WriteCount -Value $($_.PerfData.WriteCount) -PassThru |                     
 Add-Member -MemberType NoteProperty -Name WriteTime -Value $($_.PerfData.WriteTime)             
            
$perfdata             
}            
}            
}

We get round that by creating an object using select and then using Add-member to add the performance properties.

I get three instances of the MSDiskDriver_Performance  class return which I think correspond to the physical disk and the two logical disks. I need to do a bit more investigation to confirm. In the mean time it does give some interesting statistics on our disks


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: