UK PowerShell conference

There’s a one day PowerShell conference in October in London –

It’s rumoured I may be there and speaking

Posted in Powershell | Leave a comment

Windows Server 2008 EoL

Windows Server 2008 EoL on 14 January 2020

Windows Server 2008 and 2008 R2 will be end of life and no longer supported from 14 January 2020 –

There’s plenty of time to think about migrating off of the 2008 family but don’t leave it to the last minute.

Server 2008 had PowerShell v1 and 2008 R2 introduced PowerShell v2. They were good server products but its time to replace them if you haven’t already.

Posted in Windows Server 2008, Windows Server 2008 R2 | Leave a comment

Windows activation

Windows activation is usually straight forward. Put in the license key during installation, ensure the machine can connect to the Internet and wait a bit. Windows is activated.

Except today I was rebuilding some VMs and the activation didn’t work. I got a message about not being able to connect to the activation servers. The choices at this time are wait and hope it sorts itself out, try a manual activation or if all else fails and you’re prepared to lose a significant portion of your remaining lifetime try a telephone activation.

The GUI for activation was nice and simple and worked. As with most things in Windows you now have to go through more steps to get to what you need to do and then the GUI is based on a whole load of assumptions about what you want to do that often bear no relationship to reality. Since Windows Vista the GUI has become harder and harder to use to get anything done unless its a task that Microsoft thinks you’re capable of doing. The more you know about Windows the harder it is to rely on the GUI.

You can use CIM to force the activation

Get-CimInstance -ClassName SoftwareLicensingProduct -Filter “PartialProductKey IS NOT NULL” |
Invoke-CimMethod -MethodName Activate

If at first you don’t succeed put the code in a loop and keep trying

You can test the activation status

enum Licensestatus {
  Unlicensed = 0
  Licensed = 1
  OOBGrace = 2
  OOTGrace = 3
  NonGenuineGrace = 4
  Notification = 5
  ExtendedGrace = 6

Get-CimInstance -ClassName SoftwareLicensingProduct -Filter “PartialProductKey IS NOT NULL” |
select Name,  ApplicationId, @{N=’LicenseStatus’; E={[LicenseStatus]$_.LicenseStatus} }

Posted in Powershell | Leave a comment

CPU intensive processes

How do you find the most CPU intensive processes?

If you want to know the processes that are taking most CPU on your system right now then use Get-Process

PS> Get-Process | sort CPU -Descending | select -First 10

Will display the 10 processes that are running and are using the most CPU – see the CPU( s ) field.

Couple of issues with this approach. First only running processes are shown. If a process starts and runs to completion between 2 calls to Get-Process you’ll never know it happened.  Especially relevant if the process runs over night. Second, Get-Process produces a lot of information you don’t necessarily need for this task.

The alternative is to use performance counters.

PS> Get-Counter -ListSet *Process* | select CounterSetName, Description

Lists possible counter sets you can use. The Process set looks like a good possibility:

PS> Get-Counter -ListSet Process | select -ExpandProperty Counter
\Process(*)\% Processor Time
\Process(*)\% User Time
\Process(*)\% Privileged Time
\Process(*)\Virtual Bytes Peak
\Process(*)\Virtual Bytes
\Process(*)\Page Faults/sec
\Process(*)\Working Set Peak
\Process(*)\Working Set
\Process(*)\Page File Bytes Peak
\Process(*)\Page File Bytes
\Process(*)\Private Bytes
\Process(*)\Thread Count
\Process(*)\Priority Base
\Process(*)\Elapsed Time
\Process(*)\ID Process
\Process(*)\Creating Process ID
\Process(*)\Pool Paged Bytes
\Process(*)\Pool Nonpaged Bytes
\Process(*)\Handle Count
\Process(*)\IO Read Operations/sec
\Process(*)\IO Write Operations/sec
\Process(*)\IO Data Operations/sec
\Process(*)\IO Other Operations/sec
\Process(*)\IO Read Bytes/sec
\Process(*)\IO Write Bytes/sec
\Process(*)\IO Data Bytes/sec
\Process(*)\IO Other Bytes/sec
\Process(*)\Working Set – Private

Of those \Process(*)\% Processor Time looks to be what we want.

If you just run

PS> Get-Counter -Counter ‘\Process(*)\% Processor Time’

You’ll get all counters. But you can’t give a process name so you’ll have to do a bit of digging into the object returned by Get-Counter

PS> Get-Counter -Counter ‘\Process(*)\% Processor Time’ | gm

    TypeName: Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet

Name           MemberType     Definition
—-           ———-     ———-
Equals         Method         bool Equals(System.Object obj)
GetHashCode    Method         int GetHashCode()
GetType        Method         type GetType()
ToString       Method         string ToString()
CounterSamples Property       Microsoft.PowerShell.Commands.GetCounter.PerformanceCo
Timestamp      Property       datetime Timestamp {get;set;}
Readings       ScriptProperty System.Object Readings {get=$strPaths = “”…

Timestamp is the time that you retrieved the data. Countersamples gives the data for each process:

PS> $samples = Get-Counter -Counter ‘\Process(*)\% Processor Time’
PS> $samples.Timestamp

09 July 2018 10:58:34

PS> $samples.CounterSamples | select -First 1 | Format-List

Path         : \\w510w10\process(idle)\% processor time
InstanceName : idle
CookedValue  : 803.827924975895

Just selecting the top 10 processes won’t work.

PS> $samples.CounterSamples | sort CookedValue -Descending | select -f 10 | Format-List

Path         : \\w510w10\process(_total)\% processor time
InstanceName : _total
CookedValue  : 805.382717867531

Path         : \\w510w10\process(idle)\% processor time
InstanceName : idle
CookedValue  : 803.827924975895

Path         : \\w510w10\process(powershell#1)\% processor time
InstanceName : powershell
CookedValue  : 1.55479289163616

Because you get the _total and idle counts. So you need to skip them

PS> $samples.CounterSamples | sort CookedValue -Descending | select -Skip 2 -First 10 | Format-List

By default Get-Counter takes 1 sample. If you want to  multiple samples you can use the –Continuous switch which will sample continuously. Use –SampleInterval to determine the number of seconds between samples.

Alternatively, use –MaxSamples and –SampleInterval to control the number of samples in a given period but you get a sample at each sampling interval.

However you decide to sample the data you’re going to need to preserve it for future analysis. Probably easiest is to output the top process at each sampling interval to a CSV file

$samplecount = 0

while ($true) {
   $samples = Get-Counter -Counter ‘\Process(*)\% Processor Time’
   $counter = $samples.CounterSamples | sort CookedValue -Descending | select -Skip 2 -First 1

  $props = [ordered]@{
     Time = $samples.Timestamp
     Process = $counter.InstanceName
     Value = $counter.CookedValue

  New-Object -TypeName PSObject -Property $props |
   Export-Csv -Path C:\test\counters.csv -Append -NoTypeInformation

  if ($samplecount -ge 10){break}
   Start-Sleep -Seconds 10

You may see error messages like this:

Get-Counter : The data in one of the performance counter samples is not valid. View the Status
property for each PerformanceCounterSample object to make sure it contains valid data.
At line:6 char:14
+   $samples = Get-Counter -Counter ‘\Process(*)\% Processor Time’
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo          : InvalidResult: (:) [Get-Counter], Exception
     + FullyQualifiedErrorId : CounterApiError,Microsoft.PowerShell.Commands.GetCounterCommand

So you may not your data exactly 10 seconds apart.

You could use –ErrorAction to silently continue and suppress the messages. You’ll still get your 10 samples.

You can run the script from a job or put an outer loop that starts sampling every minute, 10 minutes or whatever you need.

If you see different process showing in your samples then your machine’s resources aren’t been hogged by a single process.

Posted in Powershell | Leave a comment

PowerShell not equal

The Powershell not equal operator is –ne. This how you use it.

When dealing with numbers:

PS> $a = 3
PS> $b = 5
PS> $a -ne $b

When dealing with strings you have a bit more choice:

PS> $a = ‘abcd’
PS> $b = ‘efgh’
PS> $a -ne $b

By default PowerShell is case insensitive so

PS> $a = ‘abcd’
PS> $b = ‘ABCD’
PS> $a -ne $b

If the only difference is case then –ne reports they are the same.

If you need a case insensitive test use –cne

PS> $a = ‘abcd’
PS> $b = ‘ABCD’
PS> $a -cne $b

Because there are case differences the strings are different so you get a result of True

If you need a case insensitive test use –ine so you know you’re ignoring case

PS> $a = ‘abcd’
PS> $b = ‘ABCD’
PS> $a -ine $b

The major problem with use not equal is that you’re in double negative

if X –ne Y then it means they are the same if the result is false

PS> $a = 3
PS> $b = 3
PS> $a -ne $b

Its always easier to comprehend a test for equality rather than inequality especially if you’re nesting tests.

Posted in Powershell | Leave a comment

Variable squeezing

When you’re developing code interactively how often do you set a variable and then display it to test the result? You can do that in one go using variable squeezing.

Normally you’d do:

PS> $test = 1
PS> $test

Set the variable and display the contents as two separate actions.

By enclosing the first statement in parentheses you accomplish both tasks

PS> ($test2 = 2)

Great for interactive work but you don’t want in in scripts as you’d be getting output every time you set a variable value!

Posted in Powershell | Leave a comment

MVP renewal

I received the email today stating that my MVP award has been renewed for another year – the 11th.

I’ve watched the PowerShell community grow, change and evolve over the last 12 years or so and its been an interesting and fascinating journey.

Thank you to everyone who takes the time to read my blog, listen to me speak or read my books. Without you this community wouldn’t be as strong

Posted in Powershell | 3 Comments