Quantcast
Channel: WMI – PowerShell for Windows Admins
Viewing all 140 articles
Browse latest View live

Working with profiles: 2 deleting profiles

$
0
0

I recently (1 June) showed how to discover the user profiles on your system. Now its time to delete them.

function remove-profile {            
 param (            
  [parameter(Mandatory=$true)]            
  [string]$username            
 )            
            
 $user = Get-CimInstance -Class Win32_UserAccount -Filter "Name = '$username'"             
 $profile = Get-CimInstance -Class Win32_UserProfile -Filter "SID = '$($user.SID)'"            
 $folder = Split-Path -Path $profile.LocalPath -Leaf            
            
 if ($folder -eq $username){            
  Remove-CimInstance -InputObject $profile            
 }            
 else {            
  Write-Warning -Message "Could not resolve profile and user name"             
 }            
            
}

I’m going to start with the CIM cmdlets as these are the way of the future in PowerShell v3.

Start by taking a user name as a parameter. Get the Win32_UserAccount class object representing that account. use the SID to find the profile via Win32_UserProfile.  Take the profile’s localpath and split it. The last part of the path should match the username – if it does then delete the profile otherwise throw a warning. Deleting the profile does delete the folder under c:\users

If you have to use the WMI cmdlets then its very similar

function remove-profile {            
 param (            
  [parameter(Mandatory=$true)]            
  [string]$username            
 )            
            
 $user = Get-WmiObject -Class Win32_UserAccount -Filter "Name = '$username'"             
 $profile = Get-WmiObject -Class Win32_UserProfile -Filter "SID = '$($user.SID)'"            
 $folder = Split-Path -Path $profile.LocalPath -Leaf            
            
 if ($folder -eq $username){            
  Remove-WmiObject -InputObject $profile            
 }            
 else {            
  Write-Warning -Message "Could not resolve profile and user name"             
 }            
            
}

Just the name of the cmdlets change.

You can’t use WMI to delete local accounts as explained on page 363 of PowerShell and WMI 

If you have profiles generated by AD accounts you’ll need to find the SID from the AD account and use that as the filter for deletion


WMI property names

$
0
0

A question brought it home to me that WMI property names don’t always mean what you might think they mean – this is also true of other objects but I tripped over this one with WMI so we’ll stick with that.

PS> Get-CimInstance -ClassName Win32_Desktop -Filter "Name LIKE ‘%Richard’" |
>> Format-List ScreenSaver*
>>

ScreenSaverActive     : True
ScreenSaverExecutable : C:\Windows\system32\PhotoScreensaver.scr
ScreenSaverSecure     : True
ScreenSaverTimeout    : 600

 

The ScreenSaverActive property doesn’t mean that the screen saver is currently active – it means that one has been set!   This is doubly confusing because the documentation states

ScreenSaverActive
Data type: boolean
Access type: Read-only

Screen saver is active.

Which would lead you to think that is was actually running!

The ScreenSaverSecure means that a password has been set to unlock the system once the screen saver kicks in & ScreenSaverTimeout is the idle time in seconds before the screen saver kicks in. The executable is the screen saver that will be used.

If you want to get the information with the WMI cmdlets use

PS> Get-WmiObject Win32_Desktop -Filter "Name LIKE ‘%Richard’" |
>> Format-List ScreenSaver*
>>

ScreenSaverActive     : True
ScreenSaverExecutable : C:\Windows\system32\PhotoScreensaver.scr
ScreenSaverSecure     : True
ScreenSaverTimeout    : 600

Windows 8 Networking cmdlets

$
0
0

Windows 8 brings PowerShell v3 and a whole bunch of PowerShell modules.  One such module is NETTCPIP and as the name suggests is about networking.

PowerShell v3 automatically loads modules for you so as soon as PowerShell opens try

PS> Get-NetIPConfiguration

InterfaceAlias       : Ethernet
InterfaceIndex       : 13
InterfaceDescription : NVIDIA nForce 10/100/1000 Mbps Ethernet
NetProfile.Name      : Unidentified network
IPv4Address          : 10.10.54.202
IPv6DefaultGateway   :
IPv4DefaultGateway   :
DNSServer            : fec0:0:0:ffff::1
                       fec0:0:0:ffff::2
                       fec0:0:0:ffff::3

InterfaceAlias       : WiFi
InterfaceIndex       : 12
InterfaceDescription : Qualcomm Atheros AR5007 802.11b/g WiFi Ada
NetProfile.Name      : TiscaliF23E11
IPv4Address          : 192.168.1.2
IPv6DefaultGateway   :
IPv4DefaultGateway   : 192.168.1.1
DNSServer            : 192.168.1.1

InterfaceAlias       : Bluetooth Network Connection
InterfaceIndex       : 30
InterfaceDescription : Bluetooth Device (Personal Area Network)
NetAdapter.Status    : Disconnected

One thing that you will need to do is to set up PowerShell remoting

PS> Enable-PSRemoting

WinRM Quick Configuration
Running command "Set-WSManQuickConfig" to enable remote management of this computer by using the Windows Remote
Management (WinRM) service.
This includes:
    1. Starting or restarting (if already started) the WinRM service
    2. Setting the WinRM service startup type to Automatic
    3. Creating a listener to accept requests on any IP address
    4. Enabling Windows Firewall inbound rule exceptions for WS-Management traffic (for http only).

Do you want to continue?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): a

Set-WSManQuickConfig : <f:WSManFault xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="2150859113"
Machine="localhost"><f:Message><f:ProviderFault provider="Config provider"
path="%systemroot%\system32\WsmSvc.dll"><f:WSManFault xmlns:f="
http://schemas.microsoft.com/wbem/wsman/1/wsmanfault"
Code="2150859113" Machine="RSLAPTOP01"><f:Message>WinRM firewall exception will not work since one of the network
connection types on this machine is set to Public. Change the network connection type to either Domain or Private and
try again. </f:Message></f:WSManFault></f:ProviderFault></f:Message></f:WSManFault>
At line:69 char:17
+                 Set-WSManQuickConfig -force
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Set-WSManQuickConfig], InvalidOperationException
    + FullyQualifiedErrorId : WsManError,Microsoft.WSMan.Management.SetWSManQuickConfigCommand

The emphasis of Public is mine. We have a network connection type set to public. At this point I would normally be tearing my hair out because network connection types are the ultimate pain to modify. I have hated the things since Windows Vista. No more they are now a minor inconvenience.

Look in the module NetConnection for Get-NetConnectionProfile

PS> Get-NetConnectionProfile

Name             : Unidentified network
InterfaceAlias   : Ethernet
InterfaceIndex   : 13
NetworkCategory  : Public
IPv4Connectivity : NoTraffic
IPv6Connectivity : NoTraffic

Name             : TiscaliF23E11
InterfaceAlias   : WiFi
InterfaceIndex   : 12
NetworkCategory  : Private
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic

Now we can get to it modifying is easy

PS> Set-NetConnectionProfile -InterfaceIndex 13 -NetworkCategory Private
PS> Get-NetConnectionProfile

Name             : Unidentified network
InterfaceAlias   : Ethernet
InterfaceIndex   : 13
NetworkCategory  : Private
IPv4Connectivity : NoTraffic
IPv6Connectivity : NoTraffic

Name             : TiscaliF23E11
InterfaceAlias   : WiFi
InterfaceIndex   : 12
NetworkCategory  : Private
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic

And now you can enable PowerShell remoting

Best of all the change is WMI based.  The netconnection cmdlets are created as CDXML from WMI classes new to Windows 8. Get-NetIPConfiguration is also CDXML.

CDXML is cmdlets over objects – WMI classes wrapped in XML and presented as a module

see Chapters 18 & 19 of PowerShell and WMI for more details

Windows 8 RTM startup

$
0
0

I was looking at Win32_OperatingSystem today and noticed that the last boot up time wasn’t right

PS> Get-CimInstance -ClassName Win32_OperatingSystem | select LastBootUpTime

LastBootUpTime
————–
17/08/2012 10:02:11

17 August isn’t right as I know I did a cold start this morning – or at least I think I did!

Windows 8 starts up much faster than Windows 7

Looking at the System event log the last but one entry last night was event id 64 – “The system is entering sleep.”

Looks like using the Shutdown option from Settings – Power only puts the machine to sleep.

I tried using the PowerShell stop-computer cmdlet.

Shutdown took longer than usual. 

I found an entry in the system log stating

“The kernel power manager has initiated a shutdown transition.”

Startup then took much longer than usual

PS> Get-CimInstance -ClassName Win32_OperatingSystem | select LastBootUpTime

LastBootUpTime
————–
02/09/2012 19:27:41

So looks like use the Settings – Power – Shutdown option to put the machine into a deep sleep and get very quick start up.  Use stop-computer and completely shutdown but have longer startup times.

Question now is does the deep sleep put any drain on the battery for laptops? I’ll try and find out.

Finding if the user associated with a profile is logged on

$
0
0

A forum question asked how to find if the user to whom a profile belonged was logged on. There isn’t an easy way as there isn’t an association between the profile and the log on session.

There is a quick and dirty way  though

Get-WmiObject -Class Win32_UserProfile |            
foreach {            
            
$filt =  Split-Path -Path $($_.LocalPath) -Leaf            
$loggedon = $null            
$loggedon = Get-WmiObject Win32_loggedonuser |             
 where {$_.Antecedent -like "*Name=*$filt*"} |             
 select -First 1             
            
$log = $false            
if ($loggedon){$log = $true}            
            
New-Object -TypeName PSObject -Property @{            
 Name = $filt            
 Logged = $log            
}            
}

get the profiles and for each split the Localpath (path to profile) – the leaf holds the user name

Test if you can find an instance of Win32_LoggedOnUser where the Antecedent contains the name

Display data.  Results look like this

Name           Logged

—-           ——

DefaultAppPool  False

Richard          True

NetworkService  False

LocalService    False

systemprofile   False

need to filter the system accounts out but I’ll leave that to you

Finding the drive letter of a mounted VHD

$
0
0

In Windows 8/2012 you can mount a VHD into the file system. Is there a way to discover the drive letter of the mounted VHD

function get-mountedvhdDrive {            
$disks = Get-CimInstance -ClassName Win32_DiskDrive | where Caption -eq "Microsoft Virtual Disk"            
foreach ($disk in $disks){            
 $vols = Get-CimAssociatedInstance -CimInstance $disk -ResultClassName Win32_DiskPartition             
 foreach ($vol in $vols){            
   Get-CimAssociatedInstance -CimInstance $vol -ResultClassName Win32_LogicalDisk |            
   where VolumeName -ne 'System Reserved'            
 }            
}            
}

Use Get-CimInstance to get the Win32_DiskDrive class. Filter on caption equalling "Microsoft Virtual Disk"

for each “physical” disk returned get the associated Win32_Volume and use that to get the associated Win32_Logical disk where you will find the drive letter.

Nice example of using associations in the CIM cmdlets

WMI over WSMAN

$
0
0

Every time I look at PowerShell v3 I seem to find a new way to access WMI!

I’ve covered the –ComputerName and –CimSession parameters before but to recap

We duplicate the way Get-WmiObject works:

$computer = $env:COMPUTERNAME
Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer

 

We can use CIM sessions
$cs = New-CimSession -ComputerName $computer
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $cs

 

One little known and little used capability in PowerShell v2 was the WSMAN cmdlets. These enable us to access WMI directly over WSMAN

$ruri = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_OperatingSystem"
Get-WSManInstance -ResourceURI $ruri -ComputerName $computer

This is fine for a single returned instance but where there are multiples eg disks we need to do a bit more work

$ruri = http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk

Get-WSManInstance -ResourceURI $ruri -ComputerName $computer -Enumerate |
select DeviceId, Description

It turns out that we can use these ResourceURIs with Get-CimInstance

$ruri = http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_OperatingSystem

Get-CimInstance -ResourceUri $ruri -ComputerName $computer
Get-CimInstance -ResourceUri $ruri -CimSession $cs

Better still if we are going after multiple instances

$ruri = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk"
Get-CimInstance -ResourceUri $ruri -ComputerName $computer |
select DeviceId, Description

Get-CimInstance -ResourceUri $ruri -CimSession $cs |
select DeviceId, Description

You have to use –ComputerName OR –CimSession if you use –ResourceURI.  If you don’t you make a DCOM connection to the local machine and you request will fail. You also won’t be able to use –ResourceURI if your CIM session is over DCOM

Jobs, WMI, CIM and more jobs

$
0
0

Background jobs were one of the most undervalued aspects of PowerShell v2. With the introduction of PowerShell v3 we get ways to schedule those jobs. In this post though I want to look at the new CIM cmdlets and jobs.

Using the WMI cmdlets most PowerShell users have done something like this:

PS> Get-WmiObject -Class Win32_ComputerSystem

Domain              : WORKGROUP
Manufacturer        : Hewlett-Packard
Model               : HP G60 Notebook PC
Name                : RSLAPTOP01
PrimaryOwnerName    : richard_siddaway@hotmail.com
TotalPhysicalMemory : 2951135232

The WMI cmdlets have the ability to be run as a background job by using the –AsJob parameter:

PS> Get-WmiObject -Class Win32_ComputerSystem  -AsJob

Id     Name            PSJobTypeName   State         HasMoreData     Location
–     —-            ————-   —–         ———–     ——–
4      Job4            WmiJob          Running       True            localhost

PS> Receive-Job -Id 4 -Keep

Domain              : WORKGROUP
Manufacturer        : Hewlett-Packard
Model               : HP G60 Notebook PC
Name                : RSLAPTOP01
PrimaryOwnerName    : richard_siddaway@hotmail.com
TotalPhysicalMemory : 2951135232

Notice the job type – WMI job

A number of other cmdlets have an –AsJob parameter:

PS> Get-Help * -Parameter *ASJob*

Name
—-
Get-NetConnectionProfile
Set-NetConnectionProfile
Invoke-Command
Get-WmiObject
Invoke-WmiMethod
Remove-WmiObject
Restart-Computer
Set-WmiInstance
Stop-Computer
Test-Connection

Notice that the list doesn’t include the CIM cmdlets. If you want to run those as jobs you need to use the standard job cmdlets.

PS> Start-Job -ScriptBlock {Get-CimInstance -ClassName Win32_ComputerSystem}

PS> Get-Job

Id     Name            PSJobTypeName   State
–     —-            ————-   —–
4      Job4            WmiJob          Completed
6      Job6            BackgroundJob   Completed

In this case the job type is Background job not WMI job.

One of the big things with the CIM cmdlets is CIM sessions – these are analogous to remoting sessions and also work over WSMAN

PS> $sw = New-CimSession -ComputerName $env:COMPUTERNAME

PS> Start-Job -ScriptBlock {Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $sw}

PS> Get-Job

Id     Name            PSJobTypeName
–     —-            ————-
4      Job4            WmiJob
6      Job6            BackgroundJob
8      Job8            BackgroundJob

PS> Receive-Job -Id 8 -Keep
Cannot bind argument to parameter ‘CimSession’ because it is null.
    + CategoryInfo          : InvalidData: (:) [Get-CimInstance], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.Management.Infrastructure.CimCm
   dlets.GetCimInstanceCommand
    + PSComputerName        : localhost

Oops – what happened.

The problem is that back ground jobs run in their own PowerShell process. That’s why you get the prompt back so quick. That process doesn’t contain the CIM session. The way round it is to create the CIM session as part of the job.

PS> $sb ={
>> $sw2 = New-CimSession -ComputerName $env:COMPUTERNAME
>> $sw2
>> Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $sw2
>> }
>>
PS> Start-Job -ScriptBlock $sb

You then get a job that completes and gives you data you can use.

Just remember that if you want to use CIM sessions in a job then create them as part of the job. You should also put in a line to remove them Smile


WMI –property parameter

$
0
0

One parameter that seems to get overlooked on Get-WmiObject is the –Property parameter. It is used to specify the properties you want returned.

This is what you would normally get by default:

PS> Get-WmiObject -Class Win32_Service  | select -f 1

ExitCode  : 0
Name      : AdobeARMservice
ProcessId : 1716
StartMode : Auto
State     : Running
Status    : OK

The full property list looks like this:

PS> Get-WmiObject -Class Win32_Service  | select -f 1 | fl *

PSComputerName          : RSLAPTOP01
Name                    : AdobeARMservice
Status                  : OK
ExitCode                : 0
DesktopInteract         : False
ErrorControl            : Ignore
PathName                : "C:\Program Files\Common Files\Adobe\ARM\1.0\armsvc.exe"
ServiceType             : Own Process
StartMode               : Auto
__GENUS                 : 2
__CLASS                 : Win32_Service
__SUPERCLASS            : Win32_BaseService
__DYNASTY               : CIM_ManagedSystemElement
__RELPATH               : Win32_Service.Name="AdobeARMservice"
__PROPERTY_COUNT        : 25
__DERIVATION            : {Win32_BaseService, CIM_Service, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER                : RSLAPTOP01
__NAMESPACE             : root\cimv2
__PATH                  : \\RSLAPTOP01\root\cimv2:Win32_Service.Name="AdobeARMservice"
AcceptPause             : False
AcceptStop              : True
Caption                 : Adobe Acrobat Update Service
CheckPoint              : 0
CreationClassName       : Win32_Service
Description             : Adobe Acrobat Updater keeps your Adobe software up to date.
DisplayName             : Adobe Acrobat Update Service
InstallDate             :
ProcessId               : 1716
ServiceSpecificExitCode : 0
Started                 : True
StartName               : LocalSystem
State                   : Running
SystemCreationClassName : Win32_ComputerSystem
SystemName              : RSLAPTOP01
TagId                   : 0
WaitHint                : 0
Scope                   : System.Management.ManagementScope
Path                    : \\RSLAPTOP01\root\cimv2:Win32_Service.Name="AdobeARMservice"
Options                 : System.Management.ObjectGetOptions
ClassPath               : \\RSLAPTOP01\root\cimv2:Win32_Service
Properties              : {AcceptPause, AcceptStop, Caption, CheckPoint…}
SystemProperties        : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY…}
Qualifiers              : {dynamic, Locale, provider, UUID}
Site                    :
Container               :

You can restrict the properties returned:

PS> Get-WmiObject -Class Win32_Service  -Property SystemName, Name, DisplayName | select -f 1

__GENUS          : 2
__CLASS          : Win32_Service
__SUPERCLASS     :
__DYNASTY        :
__RELPATH        : Win32_Service.Name="AdobeARMservice"
__PROPERTY_COUNT : 3
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
DisplayName      : Adobe Acrobat Update Service
Name             : AdobeARMservice
SystemName       : RSLAPTOP01
PSComputerName   :

problem is you still get the system properties (those that start __ )

PS> Get-WmiObject -Class Win32_Service  -Property SystemName, Name, DisplayName | select -f 1 | fl SystemName, Name, DisplayName

SystemName  : RSLAPTOP01
Name        : AdobeARMservice
DisplayName : Adobe Acrobat Update Service

replace the format-list (fl) by another select if you want to do anything with the object.

The new CIM cmdlets in PowerShell v3 also have a property parameter

PS> Get-CimInstance -Class Win32_Service  -Property SystemName, Name, DisplayName | select -f 1

 

Name                    : AdobeARMservice
Status                  :
ExitCode                :
DesktopInteract         :
ErrorControl            :
PathName                :
ServiceType             :
StartMode               :
Caption                 :
Description             :
InstallDate             :
CreationClassName       :
Started                 :
SystemCreationClassName :
SystemName              : RSLAPTOP01
AcceptPause             :
AcceptStop              :
DisplayName             : Adobe Acrobat Update Service
ServiceSpecificExitCode :
StartName               :
State                   :
TagId                   :
CheckPoint              :
ProcessId               :
WaitHint                :
PSComputerName          :
CimClass                : root/cimv2:Win32_Service
CimInstanceProperties   : {Caption, Description, InstallDate, Name…}
CimSystemProperties     : Microsoft.Management.Infrastructure.CimSystemProperties

This only populates the select properties but displays all properties by default!

use select again to restrict

PS> Get-CimInstance -ClassName Win32_Service  -Property SystemName, Name, DisplayName | select -f 1 | fl SystemName, Name, DisplayName

SystemName  : RSLAPTOP01
Name        : AdobeARMservice
DisplayName : Adobe Acrobat Update Service

Either way – WMI or CIM – you have to do a bit more work but the important point is that only the properties you want are returned across the network. Reduces traffic and should boost performance.

Using a WQL query returns the results shown above. This is because the –Filter parameter is turned into a WQL query.

New about files

$
0
0

PowerShell v3 features updateable help.  The help files are not quite complete at the moment but a recent update to the help that is available brought a couple of very useful files:

about_WMI

about_WQL

The first gives a good overview of WMI and the its structure.  Good background reading.

The second gives a very good start for using WMI Query Language – WQL.  It doesn’t cover everything – for instance associations are mentioned but it does give enough to work sensibly with WMI filters.

Both files are recommended reading

Get-CimClass changes

$
0
0

One thing that I don’t think I’ve mentioned is that the Get-CimClass output changed during the development process.

In PowerShell v3 RTM you can dig into a WMI class like this

Get-CimClass -ClassName Win32_OperatingSystem | select -ExpandProperty CimClassMethods
Get-CimClass -ClassName Win32_OperatingSystem | select -ExpandProperty CimClassProperties
Get-CimClass -ClassName Win32_OperatingSystem | select -ExpandProperty CimClassQualifiers
Get-CimClass -ClassName Win32_OperatingSystem | select -ExpandProperty CimSystemProperties

In at least some of the CTP versions of PowerShell v3 there were parallel, or alternate, properties you could use: Methods , Properties and Qualifiers respectively.

You may see reference to them in older posts – if you do just prefix with CimClass and you’ll be good.

Displaying data from multiple servers as HTML

$
0
0

A forum question regarding retrieving WMI based data from multiple servers and displaying it as HTML was interesting.  I would approach it like this

$servers = Get-Content -Path C:\scripts\servers.txt            
$data = @()            
foreach ($server in $servers){            
 $compdata = New-Object -TypeName PSObject -Property @{            
  Computer = $server            
  Contactable = $false            
  LastBootTime = ""            
  AllowTSConnections = $false            
 }            
            
 if (Test-Connection -ComputerName $server -Quiet -Count 1){            
   $compdata.Contactable = $true            
               
   $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $server            
   $compdata.LastBootTime = $os.ConvertToDateTime($os.LastBootUpTime)            
            
   $ts = Get-WmiObject -Namespace root\cimv2\terminalservices -Class Win32_TerminalServiceSetting -ComputerName $server -Authentication PacketPrivacy            
   if ($ts.AllowTSConnections -eq 1){            
    $compdata.AllowTSConnections = $true            
   }            
 }            
             
 $data += $compdata            
}            
$data            
$data | ConvertTo-Html | Out-File -FilePath c:\scripts\report.html            
Invoke-Item -Path c:\scripts\report.html

Put the list of servers in a text file & read it in via get-content.

use foreach to iterate over the list of servers.

For each server create an object and then test if you can ping the server. Note that the default setting for Contactable is $false so don’t need to deal with that case.

Get the WMI data and set the properties on the object.

Add the object to an array

After you’ve hit all the servers use ConvertTo-Html and write to a file with out-file.

use Invoke-Item to view the report

Number of processors in a box

$
0
0

WMI enables you find the number of processors in your system:

PS> Get-WmiObject -Class Win32_ComputerSystem | fl Number*

NumberOfLogicalProcessors : 2
NumberOfProcessors        : 1

This works fine for Windows Vista/Windows 2008 and above.

Earlier versions of Windows mis-report the number of processors – it counts the number of logical processors reports it as the number of physical processors.

Win32_Processor has the same problem on Windows 2003 and below.

There is a hotfix available from http://support.microsoft.com/kb/932370 that will correct the behaviour of these two WMI classes so that they report correctly

Account SIDs

$
0
0

A question on the forum asked about finding the accounts and SIDs on the local machine.

function get-SID {            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
            
Get-WmiObject -Class Win32_AccountSID -ComputerName $computername |            
foreach {            
 $da =  (($_.Element).Split(".")[1]).Split(",")            
 $sid = ($_.Setting -split "=")[1] -replace '"',''            
            
 $props = [ordered]@{            
 Domain = ($da[0] -split "=")[1] -replace '"',''            
 Account = ($da[1] -split "=")[1] -replace '"',''            
 SID = $sid            
 }            
             
 New-Object -TypeName PSObject -Property $props            
}            
            
}

Pass a computer name into the function – default is local machine.

Use the AccountSID class which links Win32_SystemAccount and Win32_SID.  For each returned instance clean up the data and create an object with three properties – domain, account and SID.

You will see more than you thought – some very useful information buried in there

Account SIDs revisited

$
0
0

I realised there is an easier way to get the data

function get-SID {            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
            
Get-WmiObject -Class Win32_AccountSID -ComputerName $computername |            
foreach {            
             
 $exp = "[wmi]'" + $($_.Element) + "'"            
 Invoke-Expression -Command $exp |            
 select Domain, Name, SID, LocalAccount            
}            
}

Use the wmi type accelerator with the path from the Element and you can just select the data you want.  As a bonus you can discover if the account is local or not


Account SIDs–hopefully my last word

$
0
0

Ok the embarrassing moral of this story is that you shouldn’t answer questions in a hurry at the end of the evening. 5 minutes after shutting down I realised that there is a far, far simpler way to get the info. Win32_AccountSID is a WMI linking class. It links Win32_SystemAccount and Win32_SID classes.

Get-WmiObject -Class Win32_SystemAccount | select Caption, Domain, Name, SID, LocalAccount

gets you all you need

Filtering

$
0
0

I’ve been grading the scripts in the warm up events for the Scripting Games and noticed a lot of people doing this:

Get-WmiObject -Class Win32_LogicalDisk | where {$_.DriveType -eq 3}

Ok now it works but there are a couple of things wrong with this approach.

Firstly, you are ignoring the built in capabilities of the get-wmiobject cmdlet

PS> Get-Command Get-WmiObject -Syntax

Get-WmiObject [-Class] <string> [[-Property] <string[]>] [-Filter <string>] [-Amended] [-DirectRead] [-AsJob]
[-Impersonation <ImpersonationLevel>] [-Authentication <AuthenticationLevel>] [-Locale <string>]
[-EnableAllPrivileges] [-Authority <string>] [-Credential <pscredential>] [-ThrottleLimit <int>] [-ComputerName
<string[]>] [-Namespace <string>] [<CommonParameters>]

Get-WmiObject [[-Class] <string>] [-Recurse] [-Amended] [-List] [-AsJob] [-Impersonation <ImpersonationLevel>]
[-Authentication <AuthenticationLevel>] [-Locale <string>] [-EnableAllPrivileges] [-Authority <string>] [-Credential
<pscredential>] [-ThrottleLimit <int>] [-ComputerName <string[]>] [-Namespace <string>] [<CommonParameters>]

Get-WmiObject -Query <string> [-Amended] [-DirectRead] [-AsJob] [-Impersonation <ImpersonationLevel>] [-Authentication
<AuthenticationLevel>] [-Locale <string>] [-EnableAllPrivileges] [-Authority <string>] [-Credential <pscredential>]
[-ThrottleLimit <int>] [-ComputerName <string[]>] [-Namespace <string>] [<CommonParameters>]

Get-WmiObject [-Amended] [-AsJob] [-Impersonation <ImpersonationLevel>] [-Authentication <AuthenticationLevel>]
[-Locale <string>] [-EnableAllPrivileges] [-Authority <string>] [-Credential <pscredential>] [-ThrottleLimit <int>]
[-ComputerName <string[]>] [-Namespace <string>] [<CommonParameters>]

Get-WmiObject [-Amended] [-AsJob] [-Impersonation <ImpersonationLevel>] [-Authentication <AuthenticationLevel>]
[-Locale <string>] [-EnableAllPrivileges] [-Authority <string>] [-Credential <pscredential>] [-ThrottleLimit <int>]
[-ComputerName <string[]>] [-Namespace <string>] [<CommonParameters>]

Notice the filter parameter in the first parameter set.

When you run Get-WMIObject in effect you are running a WQL query

“SELECT * FROM Win32_LogicalDisk”

if you move the filter into the query it changes to

“SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3”

This is coded in the cmdlet as

Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType = 3"

Why is this better?

Because you are doing less work against the WMI repository – therefore more efficient.

Also if you are running against a remote machine filtering in the WMI query means you bring less data back across the network which makes you whole process more efficient.

Bottom line – filter as early as you sensibly can and preferably on the remote machine.

CIM cmdlets and remote access

$
0
0

When you used the WMI cmdlets

Get-WmiObject -Class Win32_logicalDisk -ComputerName RSLAPTOP01

You were using DCOM to access the remote machine. Even if you accessed the local machine you were using DCOM.

This changes in PowerShell v3 when using the CIM cmdlets.

If you don’t use a computername

Get-CimInstance -ClassName Win32_logicalDisk

You use DCOM to access the local machine.

If you use –computername

Get-CimInstance -ClassName Win32_logicalDisk -ComputerName RSLAPTOP01

You use WSMAN to access the machine named – irrespective of if it is local or remote

A further complication is that the named machine has to be running WSMAN 3.0 i.e. PowerShell v3 is installed.

If you try to access a PowerShell v2 (WSMAN 2.0) machine with the CIM cmdlets you will get an error. The way round that is to create a CIMsession using DCOM as the transport protocol. If you want to learn how to do that you’ll have to wait until after my session at the PowerShell Summit in April or buy a copy of PowerShell and WMI from www.manning.com/siddaway2

I saw a number of people using the CIM cmdlets in the scripting games without thought to connectivity issues like this.

Network adapters

$
0
0

The WMI classes Win32_NetworkAdapter and Win32_NetworkAdapterConfiguration have seen a lot of use over the years. They can be a bit fiddly to use which is why the NetAdapter module in Windows 8/2012 is a so welcome.

Lets start by looking at basic information gathering

PS> Get-NetAdapter | ft -a

Name     InterfaceDescription                        ifIndex Status MacAddress        LinkSpeed
—-     ——————–                        ——- —— ———-        ———
Ethernet NVIDIA nForce 10/100/1000 Mbps Ethernet          13 Up     00-1F-16-63-F5-DF  100 Mbps
WiFi     Qualcomm Atheros AR5007 802.11b/g WiFi Adapter   12 Up     00-24-2B-2F-9C-A5   54 Mbps

We get the Name & description, status, MAC address and link speed as the default display. Contrast with Win32_NetworkAdapter for the same two interfaces

ServiceName      : athr
MACAddress       : 00:24:2B:2F:9C:A5
AdapterType      : Ethernet 802.3
DeviceID         : 10
Name             : Qualcomm Atheros AR5007 802.11b/g WiFi Adapter
NetworkAddresses :
Speed            : 54000000

ServiceName      : NVNET
MACAddress       : 00:1F:16:63:F5:DF
AdapterType      : Ethernet 802.3
DeviceID         : 11
Name             : NVIDIA nForce 10/100/1000 Mbps Ethernet
NetworkAddresses :
Speed            : 100000000

Notice the ifIndex from Get-NetAdapter & DeviceId from Win32_NetworkAdapter.  Two different numbers to identify the device.

What else can Get-NetAdapter tell us:

PS> Get-NetAdapter  -Name Ethernet | fl *

ifAlias                                          : Ethernet
InterfaceAlias                                   : Ethernet
ifIndex                                          : 13
ifDesc                                           : NVIDIA nForce 10/100/1000 Mbps Ethernet
ifName                                           : Ethernet_7
DriverVersion                                    : 73.3.0.0
LinkLayerAddress                                 : 00-1F-16-63-F5-DF
MacAddress                                       : 00-1F-16-63-F5-DF
Status                                           : Up
LinkSpeed                                        : 100 Mbps
MediaType                                        : 802.3
PhysicalMediaType                                : 802.3
AdminStatus                                      : Up
MediaConnectionState                             : Connected
DriverInformation                                : Driver Date 2010-03-04 Version 73.3.0.0 NDIS 6.20
DriverFileName                                   : nvmf6232.sys
NdisVersion                                      : 6.20
ifOperStatus                                     : Up
Caption                                          :
Description                                      :
ElementName                                      :
InstanceID                                       : {188C370D-AD90-46F3-8AD2-0C10AFB6490C}
CommunicationStatus                              :
DetailedStatus                                   :
HealthState                                      :
InstallDate                                      :
Name                                             : Ethernet
OperatingStatus                                  :
OperationalStatus                                :
PrimaryStatus                                    :
StatusDescriptions                               :
AvailableRequestedStates                         :
EnabledDefault                                   : 2
EnabledState                                     : 5
OtherEnabledState                                :
RequestedState                                   : 12
TimeOfLastStateChange                            :
TransitioningToState                             : 12
AdditionalAvailability                           :
Availability                                     :
CreationClassName                                : MSFT_NetAdapter
DeviceID                                         : {188C370D-AD90-46F3-8AD2-0C10AFB6490C}
ErrorCleared                                     :
ErrorDescription                                 :
IdentifyingDescriptions                          :
LastErrorCode                                    :
MaxQuiesceTime                                   :
OtherIdentifyingInfo                             :
PowerManagementCapabilities                      :
PowerManagementSupported                         :
PowerOnHours                                     :
StatusInfo                                       :
SystemCreationClassName                          : CIM_NetworkPort
SystemName                                       : RSLAPTOP01
TotalPowerOnHours                                :
MaxSpeed                                         :
OtherPortType                                    :
PortType                                         :
RequestedSpeed                                   :
Speed                                            : 100000000
UsageRestriction                                 :
ActiveMaximumTransmissionUnit                    : 1500
AutoSense                                        :
FullDuplex                                       : True
LinkTechnology                                   :
NetworkAddresses                                 : {001F1663F5DF}
OtherLinkTechnology                              :
OtherNetworkPortType                             :
PermanentAddress                                 : 001F1663F5DF
PortNumber                                       : 0
SupportedMaximumTransmissionUnit                 :
AdminLocked                                      : False
ComponentID                                      : pci\ven_10de&dev_0760
ConnectorPresent                                 : True
DeviceName                                       : \Device\{188C370D-AD90-46F3-8AD2-0C10AFB6490C}
DeviceWakeUpEnable                               : False
DriverDate                                       : 2010-03-04
DriverDateData                                   : 129121344000000000
DriverDescription                                : NVIDIA nForce 10/100/1000 Mbps Ethernet
DriverMajorNdisVersion                           : 6
DriverMinorNdisVersion                           : 20
DriverName                                       : \SystemRoot\system32\DRIVERS\nvmf6232.sys
DriverProvider                                   : NVIDIA
DriverVersionString                              : 73.3.0.0
EndPointInterface                                : False
HardwareInterface                                : True
Hidden                                           : False
HigherLayerInterfaceIndices                      : {26}
IMFilter                                         : False
InterfaceAdminStatus                             : 1
InterfaceDescription                             : NVIDIA nForce 10/100/1000 Mbps Ethernet
InterfaceGuid                                    : {188C370D-AD90-46F3-8AD2-0C10AFB6490C}
InterfaceIndex                                   : 13
InterfaceName                                    : Ethernet_7
InterfaceOperationalStatus                       : 1
InterfaceType                                    : 6
iSCSIInterface                                   : False
LowerLayerInterfaceIndices                       :
MajorDriverVersion                               : 73
MediaConnectState                                : 1
MediaDuplexState                                 : 2
MinorDriverVersion                               : 30
MtuSize                                          : 1500
NdisMedium                                       : 0
NdisPhysicalMedium                               : 14
NetLuid                                          : 1688849977704448
NetLuidIndex                                     : 7
NotUserRemovable                                 : False
OperationalStatusDownDefaultPortNotAuthenticated : False
OperationalStatusDownInterfacePaused             : False
OperationalStatusDownLowPowerState               : False
OperationalStatusDownMediaDisconnected           : False
PnPDeviceID                                      : PCI\VEN_10DE&DEV_0760&SUBSYS_360A103C&REV_A2\3&2411E6FE&0&50
PromiscuousMode                                  : False
ReceiveLinkSpeed                                 : 100000000
State                                            : 2
TransmitLinkSpeed                                : 100000000
Virtual                                          : False
VlanID                                           :
WdmInterface                                     : False
PSComputerName                                   :
CimClass                                         : ROOT/StandardCimv2:MSFT_NetAdapter
CimInstanceProperties                            : {Caption, Description, ElementName, InstanceID…}
CimSystemProperties                              : Microsoft.Management.Infrastructure.CimSystemProperties

Notice the CimClass property ROOT/StandardCimv2:MSFT_NetAdapter   – this is one of the new WMI classes introduced in Windows 8.  Does this class have any methods?

Get-CimClass -Namespace ROOT/StandardCimv2 -ClassName MSFT_NetAdapter | select -ExpandProperty CimClassMethods

Name
—-
RequestStateChange
SetPowerState
Reset
EnableDevice
OnlineDevice
QuiesceDevice
SaveProperties
RestoreProperties
Enable
Disable
Restart
Lock
Unlock
Rename

These will be investigated in other posts – maybe we get cmdlets to work with these as well

Network Adapters–Disable/Enable

$
0
0

Last time we saw the Get-NetAdapter cmdlet from the NetAdapter module

PS> Get-NetAdapter | ft Name, InterfaceDescription, Status -a

Name     InterfaceDescription                           Status
—-     ——————–                           ——
Ethernet NVIDIA nForce 10/100/1000 Mbps Ethernet        Up
WiFi     Qualcomm Atheros AR5007 802.11b/g WiFi Adapter Up

If you look in the module you also find Disable-NetAdapter & Enable-NetAdapter

PS> Disable-NetAdapter -Name Wifi -Confirm:$false
PS> Get-NetAdapter | ft Name, InterfaceDescription, Status -a

Name     InterfaceDescription                           Status
—-     ——————–                           ——
Ethernet NVIDIA nForce 10/100/1000 Mbps Ethernet        Up
WiFi     Qualcomm Atheros AR5007 802.11b/g WiFi Adapter Disabled

PS> Enable-NetAdapter -Name Wifi -Confirm:$false
PS> Get-NetAdapter | ft Name, InterfaceDescription, Status -a

Name     InterfaceDescription                           Status
—-     ——————–                           ——
Ethernet NVIDIA nForce 10/100/1000 Mbps Ethernet        Up
WiFi     Qualcomm Atheros AR5007 802.11b/g WiFi Adapter Up

You can also enable/disable based on an Input Object, the alias (-ifalias) or the description (-InterfaceDescription)

PS> Get-NetAdapter -Name Wifi | Disable-NetAdapter -Confirm:$false
PS> Get-NetAdapter | ft Name, InterfaceDescription, Status -a

Name     InterfaceDescription                           Status
—-     ——————–                           ——
Ethernet NVIDIA nForce 10/100/1000 Mbps Ethernet        Up
WiFi     Qualcomm Atheros AR5007 802.11b/g WiFi Adapter Disabled

PS> Get-NetAdapter -Name Wifi | Enable-NetAdapter -Confirm:$false
PS> Get-NetAdapter | ft Name, InterfaceDescription, Status -a

Name     InterfaceDescription                           Status
—-     ——————–                           ——
Ethernet NVIDIA nForce 10/100/1000 Mbps Ethernet        Up
WiFi     Qualcomm Atheros AR5007 802.11b/g WiFi Adapter Up

What’s the alias?

PS> Get-NetAdapter | ft Name, InterfaceDescription, ifAlias, InterfaceAlias -a

Name     InterfaceDescription                           ifAlias  InterfaceAlias
—-     ——————–                           ——-  ————–
Ethernet NVIDIA nForce 10/100/1000 Mbps Ethernet        Ethernet Ethernet
WiFi     Qualcomm Atheros AR5007 802.11b/g WiFi Adapter WiFi     WiFi

If you want to use these cmdlets against remote machines you can run them through a CIMsession

Viewing all 140 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>