PowerShell for Windows Admins


April 14, 2016  8:27 AM

Folder creation dates from WMI

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell, 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.

 

April 14, 2016  4:50 AM

PowerShell Summit 2016 recordings

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The recordings from this years PowerShell Summit are now available:

http://powershell.org/wp/2016/04/13/powershell-devops-global-summit-videos-online/

https://www.youtube.com/playlist?list=PLfeA8kIs7Coc1Jn5hC4e_XgbFUaS5jY2i


April 13, 2016  3:49 AM

IT Ops Education program and Scholarship

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
DevOps, IT education, Powershell

Do you know a young person in the USA that is just starting their IT career and would benefit from an intensive training program and scholarship?

Point them to the DevOps Collective site (DevOps Collective is the parent organization for powershell.org)  https://devopscollective.org/2016/04/04/announcing-the-getgoing-it-ops-education-program-scholarship/

Initially this program is US only but we hope to make a global program in years to come


April 12, 2016  3:33 PM

Monitor Info

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell, WMI

A question on the forum about combining information from 2 CIM classes produced this:

function Get-MonitorInfo {
[CmdletBinding()]
param(
$computername = $env:COMPUTERNAME
)

$cs = New-CimSession -ComputerName $computername

$monitors =  Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorId -Filter “Active = ‘$true'” -CimSession $cs

foreach ($monitor in $monitors) {

$in = ($monitor.InstanceName).Replace(‘\’, ‘\\’)
Write-Verbose -Message $in
$dp = Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams -Filter “InstanceName = ‘$in'” -CimSession $cs

$name = ”

foreach ($c in $monitor.UserFriendlyName){
if ($c -ne ’00’){$name += [char]$c}
}
$type = ‘Unknown’
switch ($dp.VideoInputType){
0 {$type = ‘Analog’}
1 {$type = ‘Digital’}
}

New-Object -TypeName PSObject -Property @{
Name = $name
Type = $type
}
}

Remove-CimSession -CimSession $cs
}

Create a CIM session to the computer. Get the instances of the WmiMonitorId class. Iterate through them and find the matching WmiMonitorBasicDisplayParams class instance.

The InstanceName of the monitor will look like this:

DISPLAY\GSM598F\4&19086f00&0&UID200195_0

you need to replace \ by \\ to use the value in a CIM query because \ is treated as the escape character and you have to escape it to use it

Translate the UserFriendly name by converting the byte array to a string and determine the VideoInputType using the switch.

Create an object and output


April 4, 2016  7:28 AM

PowerShell Summit: CIM Deep Dive

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell, Windows 10

A big thank you to everyone who attended my Summit pre-conference workshop. The interaction was great and I really enjoyed it even though I was feeling the efffects of my flight the previous day.

One thing we discovered was that good old dependable calc has changed. On a Windows 10 (build 14295 and last couple of builds) its now calculator.exe.

PS> Get-CimInstance -ClassName Win32_Process -Filter “Name LIKE ‘calc%'”

ProcessId Name           HandleCount WorkingSetSize VirtualSize
——— —-           ———– ————– ———–
1400      Calculator.exe 373         56770560       336953344

On Windows 2012 r2 its still calc.exe which caused a bit of confusion until we realised what was happening


April 1, 2016  8:53 AM

MVP renewal 2016

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Its April first and the email arrives mid-afternoon. My MVP award has been renewed for another year (9th consecutive year)

I still really appreciate the recognition this award bestows and hope to keep working to make the PowerShell community even better in the next 12 months


March 31, 2016  1:01 PM

IIS information

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, IIS, Powershell, WMI

In my recent post about getting server information from a IIS web server I said I post about getting similar information from later machines.

You still have the root\MirosoftIISv2 namespace available if you install the IIS 6.0 tools but one question to keep in mind – how long will they continue to be available?

Your alternative is the root\webadministration names space. You can use the Site class to get the relevant information

$serverdata = @()
Get-CimInstance -Namespace root\webadministration -ClassName Site -ComputerName $env:COMPUTERNAME |
foreach {

$serverdata += New-Object -TypeName PSObject -Property @{
Port = [string]::Join(‘,’, ($_.Bindings | select -ExpandProperty BindingInformation))
SiteName = $_.Name
SiteId = $_.id
PSComputerName = $_.PSComputerName
Status = Invoke-CimMethod -InputObject $_ -MethodName GetState | select -ExpandProperty ReturnValue
}
}
$serverdata

Remember that COM objects are inert so you can’t call the method directly on the object. otherwise the info is about the same


March 31, 2016  11:21 AM

European PowerShell Conference 2016–few places left

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

There are still a few places left at the European PowerShell conference next month – http://www.psconf.eu/

There’s a terrific line up of speakers and I really recommend you get there if you can


March 30, 2016  10:44 AM

IIS 6.0 server information

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, IIS 6.0, Powershell, WMI

A question of the forum asked about getting data from IIS 6.0 servers

One of the ways to access this data is to use CIM (WMI). IIS 6.0 has the root\MicrosoftIIsV2  namespace. Later versions of Windows server also have a root\webadministration namespace which is preferred.

The original question asked about IIS 6.0 – I’ll show the same functionality using the later namespace in the next post

This based on the original code in the question and isn’t necessarily how I would do it from scratch

$file = Get-Content “C:\Temp\PowerShellScripts\IISQuery\servers.txt”
$OutputDir = “C:\Temp\PowerShellScripts\IISQuery\Output”
$OutputFile = Join-Path $OutputDir “IIStest.csv”
$serverdata = @()

foreach ($computername in $file)
{
$IISWebServer = Get-WmiObject -Namespace root\MicrosoftIIsV2 -Class IISWEbServer -ComputerName $computername -Authentication 6
foreach ($webserver in $IISWebServer) {

$IISWebServerSet = Get-WmiObject -Namespace root\MicrosoftIISv2 -Class IISWebServerSetting -ComputerName $computername -Filter “Name=’$($webserver.Name)'”  -Authentication 6

$serverdata += New-Object -TypeName PSObject -Property @{
PScomputername = $IISWebServerSet.PScomputername
ServerComment = $IISWebServerSet.ServerComment
SiteStatus = $webserver.ServerState
Bindings = [string]::join(‘;’,($IISWebServerSet.ServerBindings | select -expand hostname))
Port = [string]::join(‘;’,($IISWebServerSet.ServerBindings | select -expand Port))
SiteName = $IISWebServerSet.Name
}

} ## end of foreach ($webserver in $IISWebServer)

}  ## end of foreach ($computername in $file)
$serverdata | Export-Csv -Path $OutputFile –NoTypeInformation

Start by defining input and output files and an empty array

Loop through the servers and get the IISWebserver class instance. You’ll get one object per web site. Loop through the sites and get the IISWebServerSetting class for that site (using –Filter).

Create and output object and add to the array

Export the array to a csv file

There are a few improvements that could be made to this to make it more efficient that I’ll cover in a later post


March 22, 2016  12:46 PM

Breaking CIM sessions

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell

A CIM session is analogous to a PowerShell remoting session but for CIM based cmdlets – the CIM cmdlets themselves and any CDXML based cmdlets e.g. the networking cmdlets

By default a CIM session uses WSMAN as its transport protocol – the same as remoting. You do have the choice to create a CIM session using DCOM for transport (same as the WMI cmdlets use)

I’ve always maintained that DCOM based sessions could be broken if the remote machine was re-started. This was based on the testing I did when writing PowerShell and WMI.

Some recent information cast doubt on that assertion though.  I’ve digging into CIM sessions recently and have what I think is a definitive statement on DCOM based CIM sessions.

If you create a DCOM based CIM session to a machine running PowerShell 2.0 from a machine running PowerShell 3.0 (or PowerShell 4.0 – I haven’t tested recently but remember doing this when writing the CIM section of PowerShell in Depth) access the remote machine and then restart and attempt to use the session – it will break like this:

$dopt = New-CimSessionOption -Protocol Dcom
$dcs = New-CimSession -ComputerName W8R2STD01 -SessionOption $dopt
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $dcs

SystemDirectory   Organization     BuildNumber      RegisteredUser   SerialNumber     Version          PSComputerName
—————   ————     ———–      ————–   ————     ——-          ————–
C:\Windows\sys…                  7601             Windows User     00477-179-000… 6.1.7601         W8R2STD01
Restart-Computer -ComputerName W8R2STD01
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $dcs
Get-CimInstance : Access is denied.
At line:1 char:1
+ Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $dcs
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (root\cimv2:Win32_OperatingSystem:String) [Get-CimInstance], CimExcept
ion
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName        : W8R2STD01

The CIM session will usually become usable again after a period of time.

If you repeat the experiment using WSMAN or DCOM sessions to machines running PowerShell 3.0 or above the command to use the session is effectively paused until the session is responsive – this can take a little time

A machine running PowerShell 5.0 RTM can create a CIM session to PowerShell 2.0 (DCOM)  or later (DCOM or WSMAN) and the command is effectively paused until the remote machine is up.

The only time I can see the need to use a DCOM based CIM session is to access a PowerShell 2.0 machine – under any other circumstances I’d recommend using the default WSMAN based sessions.

Bottom line is that DCOM based sessions can be broken under specific circumstances that hopefully with time will disappear.


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: