Monthly Archive

Loading assemblies

PowerShell is .NET based but doesn’t load all available .NET assemblies when it starts.

 

Many people still use something  like

[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')

 

to load additional assemblies.  This is a hang over from PowerShell v1 when there wasn’t another way to perform the load.

The LoadWithPartialName method has been deprecated - https://msdn.microsoft.com/en-us/library/12xc5368(v=vs.110).aspx – and shouldn’t be used.

 

Your alternatives are:

Add-Type -AssemblyName System.Windows.Forms

 

or in PowerShell v5

using assembly System.Windows.Forms

using namespace System.Windows.Forms

 

can be used

Free ebook: IoT

A free ebook from Manning: Using the Web to Build the IoT is a collection of six hand-picked chapters that introduce the key technologies and concepts for building the application layer of the IoT.  The page is here: http://bit.ly/1SUJW0P

WinOps conference

The WinOps conference is dedicated to ‘Windows in a DevOps World’  Its in London 24 May 2016. I’ll be speaking as will Jeffrey Snover and Ed Wilson of Microsoft.

 

More details from http://winops.org/

 

Hope to see you there

Windows Server 2016 TP5 Cumulative Update

An update – KB 3157663 – should be installed BEFORE installing any roles, features or applications into a TP5 system.

 

Finding the update isn’t easy – no links from the TP5 pages and doesn’t show in search on Bing or if search microsoft.com

 

You can find it here:

https://support.microsoft.com/en-us/kb/3157663

 

Lets hope RTM is a bit more organised

Windows Server 2016 TP5 now available

Microsoft have released Technology Preview 5 (TP5) of Server 2016 today.

 

Its available from MSDN and the evaluations site

 

Lots of new stuff to try out

New variables with the variable cmdlets

 

So you have some data in csv format:

column1 column2 column3 column4
------- ------- ------- -------
a1      b1      c1      d1
a1      b2      c1      d1
a1      b3      c1      d1
a2      b3      c1      d1
a2      b4      c1      d1
a2      b3      c1      d1
a3      b5      c1      d1
a3      b6      c1      d1
a3      b7      c1      d1
a4      b5      c1      d1

 

In a variable $cd

 

You want colum1 and column2 in a new variable

 

Simplest way is probably

$new1 = $cd | select Column1, column2

 

The *-Variable cmdlets don’t get out much so I thought examples using them would be useful

You could also use the New-Variable cmdlet

New-Variable -Name new2 -Value ($cd | select Column1, column2)

 

Set-Variable also works

Set-Variable -Name new3 -Value ($cd | select Column1, column2)

PowerShell team announcements

A few announcements from the PowerShell Team that I’m catching up on.

 

The Microsoft.PowerShell.Archive module is now open source

https://blogs.msdn.microsoft.com/powershell/2016/04/25/the-archive-module-is-now-open-source/

 

The archive module was introduced in WMF 5.0. Its now available on the PowerShell Gallery for installation on WMF 4.0. Any future updates will be through the gallery.

 

The version in the gallery is 1.0.1.0 as opposed to 1.0.0.0 that ships with WMF 5.0

 

You can now view the contents of files directly in the PowerShell gallery

https://blogs.msdn.microsoft.com/powershell/2016/04/21/view-file-content-feature-is-available-on-the-gallery/

 

A DSC toolkit for working with Amazon Web Services (AWS) is now available

https://blogs.msdn.microsoft.com/powershell/2016/04/20/aws-dsc-toolkit/

 

WMF 5.1 will become available when Windows Server 2016 ships

https://blogs.msdn.microsoft.com/powershell/2016/04/06/windows-management-framework-5-0-updates-and-wmf-5-1/

 

WMF 5.1 will contain the changes and bug fixes introduced since WMF 5.0 shipped. Many of these have been available on Windows Insider preview builds

PowerShell certifications revisited

Years ago (seems like decades so much has happened) I published my view on PowerShell certification:

https://richardspowershellblog.wordpress.com/2008/11/17/powershell-certifications/

 

A recent comment on the post asked if I still felt the same way.

 

Its not a topic I’d thought about all that much to be honest but having reflected on the matter I still believe what I wrote back in 2008 – the world doesn’t need a PowerShell certification.

 

I’ve stated it many times and will keep stating it – PowerShell isn’t important. Its what you can do with it that matters.

 

Very few people are employed as full time creators of PowerShell code –even today. They are  employed as administrators of X (and often Y, Z, A and B etc etc).

 

PowerShell provides a tool to administer most of things in your Windows environment (and quite a few non-Windows items as well). Having a certification in the

 

PowerShell language won’t help you administer Windows, Active directory, Exchange, SQL Server, VMware or network switches. You need to know what you’re doing before you can automate it!!!

 

At recent PowerShell Summits we’ve run a VERIFIED EFFECTIVE exam. The pass rates have been abysmal – and that’s for people who attended a pre-conference workshop on the topic! See:

http://powershell.org/wp/2016/04/22/verified-effective-exam-results/

 

We won’t be offering the exam at the next Summit – the results don’t measure up to the effort put into it.

 

The world isn’t really ready for a PowerShell certification and I suspect that it never will be.

Cim session oddity

The CIM cmdlets were introduced with PowerShell 3.0.  You can use the –ComputerName parameter to access a remote machine or, if you need to run multiple commands to the remote machine, you can create a CIM session.

 

CIM sessions are analogous to PowerShell remoting sessions and use WSMAN by default to connect to the remote machine:

PS> $c12 = New-CimSession -ComputerName W12R2SUS

PS> Get-CimInstance -CimSession $c12 -ClassName Win32_OperatingSystem | fl

SystemDirectory : C:\Windows\system32
Organization    :
BuildNumber     : 9600
RegisteredUser  : Windows User
SerialNumber    : 00252-00107-57895-AA282
Version         : 6.3.9600
PSComputerName  : W12R2SUS

 

In this case I’m accessing a Windows 2012 R2 system

 

If you try to create a CIM session to a machine running PowerShell 2.0 it will appear to work but you’ll get an error when you try to access the session:

PS> $c8 = New-CimSession -ComputerName W8R2STD01
PS> Get-CimInstance -CimSession $c8 -ClassName Win32_OperatingSystem | fl
Get-CimInstance : The WS-Management service cannot process the request. A DMTF resource URI was used to access a non-DMTF class. Try again using a non-DMTF resource URI.
At line:1 char:1
+ Get-CimInstance -CimSession $c8 -ClassName Win32_OperatingSystem | fl
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (root\cimv2:Win32_OperatingSystem:String) [Get-CimInstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80338139,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
    + PSComputerName        : W8R2STD01

 

The reason is that the version of WSMAN installed with with PowerShell 2.0 (WSMAN 2.0) isn’t compatible with CIM sessions which expect WSMAN 3.0

 

One option is to use a DCOM based session:

PS> $opt = New-CimSessionOption -Protocol Dcom
PS> $c8D = New-CimSession -ComputerName W8R2STD01 -SessionOption $opt
PS> Get-CimInstance -CimSession $c8D -ClassName Win32_OperatingSystem | fl

SystemDirectory : C:\Windows\system32
Organization    :
BuildNumber     : 7601
RegisteredUser  : Windows User
SerialNumber    : 00477-179-0000007-84050
Version         : 6.1.7601
PSComputerName  : W8R2STD01

 

PowerShell MVP Jeff Hicks discovered that if you use a filter parameter with Get-CimInstance you can access PowerShell 2.0 machines using a WSMAN based CIM session

PS> Get-CimInstance -CimSession $c8 -ClassName Win32_OperatingSystem -Filter "Caption LIKE '%'"  | fl

SystemDirectory : C:\Windows\system32
Organization    :
BuildNumber     : 7601
RegisteredUser  : Windows User
SerialNumber    : 00477-179-0000007-84050
Version         : 6.1.7601
PSComputerName  : W8R2STD01

 

In this case you’re filtering on the Caption being like any characters

 

I stood in for a speaker who was ill at the recent European PowerShell conference and part of the session was on using CIM sessions. This issue came up and I decided to investigate a bit closer

Without a filter:

PS> Get-CimInstance -CimSession $c8 -ClassName Win32_OperatingSystem -Verbose
VERBOSE: Perform operation 'Enumerate CimInstances' with following parameters, ''namespaceName' =
root\cimv2,'className' = Win32_OperatingSystem'.
Get-CimInstance : The WS-Management service cannot process the request. A DMTF resource URI was used to access a
non-DMTF class. Try again using a non-DMTF resource URI.
At line:1 char:1
+ Get-CimInstance -CimSession $c8 -ClassName Win32_OperatingSystem -Ver ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (root\cimv2:Win32_OperatingSystem:String) [Get-CimInstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80338139,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
    + PSComputerName        : W8R2STD01

VERBOSE: Operation 'Enumerate CimInstances' complete.

 

An attempt is made to enumerate the instances of the Win32_OperatingSystem class

 

If you use a filter

PS> Get-CimInstance -CimSession $c8 -ClassName Win32_OperatingSystem -Filter "Caption LIKE '%'"  -Verbose | fl
VERBOSE: Perform operation 'Query CimInstances' with following parameters, ''queryExpression' = SELECT * FROM
Win32_OperatingSystem WHERE Caption LIKE '%','queryDialect' = WQL,'namespaceName' = root\cimv2'.

SystemDirectory : C:\Windows\system32
Organization    :
BuildNumber     : 7601
RegisteredUser  : Windows User
SerialNumber    : 00477-179-0000007-84050
Version         : 6.1.7601
PSComputerName  : W8R2STD01

VERBOSE: Operation 'Query CimInstances' complete.

 

You’re sending a WQL  query to the remote machine.

 

My current theory is that Get-CimInstance is trying to enumerate the instances of a particular class (in a similar way to Get-WSmnaInstance does) and that fails due to the WSMAN version mismatch.  Using the Filter bypasses the enumeration allowing it to work.

 

This is a totally undocumented feature and there is no guarantee it will continue to work in future versions. Until PowerShell 2.0 is gone from you environment be aware that its an option but be careful

Folder creation dates from WMI

A question on the powershell.org about finding the creation date of folders raises some interesting points

 

To find a folder’s creation date use:

Get-WmiObject -Class Win32_Directory -Filter "Drive='C:' AND Path = '\\users\\$user\\'" | select Name, @{N='Creation date'; E={$_.ConvertToDateTime($_.CreationDate)}}

 

OR

 

Get-CimInstance -ClassName Win32_Directory -Filter "Drive='C:' AND Path = '\\users\\$user\\'" | select Name, CreationDate

 

If you use Get-WmiObject the date is returned in the form

20160128110039.938756+000

 

Which is why you need to perform the conversion using the ConvetToDateTime method that PowerShell adds to every WMI object.

 

Get-CimInstance automatically performs the conversion for you.

 

The other interesting part is the filter

"Drive='C:' AND Path = '\\users\\$user\\'"

 

Note that it’s wrapped in double quotes. Each of the values is a string so HAS to be in single quotes. Also note that you need to double the \ characters as WMI treats a single \ as an escape character so you have to escape the escape character.