Getting single, specific drive status using powershell? - powershell

Running this:
$WMI = Get-WMIObject -Class Win32_DiskDrive
ForEach ($Drive in $WMI){
$Drive.DeviceID + ": " + $Drive.Status
}
Returns results like:
\\.\PHYSICALDRIVE1: OK
\\.\PHYSICALDRIVE0: OK
\\.\PHYSICALDRIVE2: OK
\\.\PHYSICALDRIVE3: OK
Is there an easy way to restrict results to \.\PHYSICALDRIVE0?
Basically, I am trying to return a simple "OK" for Physical Drive 0's health.
I tried the following:
$WMI = Get-WMIObject -Class Win32_DiskDrive
ForEach ($Drive in $WMI | Where $Drive.DeviceID -Contains "\\.\PHYSICALDRIVE0"){
$Drive.Status
}
But nothing is outputted (at all). How would I restrict the status output to just the Physical Drive 0 from DeviceID?

I would do it this way:
$WMI = Get-WMIObject -Class Win32_DiskDrive
ForEach ($Drive in $WMI) {
if ($Drive.DeviceID -contains "\\.\PHYSICALDRIVE0") {
$Drive.Status
}
}
You look thru $wmi and check if each value contains this specific value.
If you have a match, it will show the Disk status.

There are many ways, depending on how specific you wish to be:
Get-WMIObject -Class Win32_DiskDrive | Where-Object DeviceID -eq '\\.\PHYSICALDRIVE0'
Get-WMIObject -Class Win32_DiskDrive | Where-Object DeviceID -match 'E0$'
Get-WMIObject -Class Win32_DiskDrive | Where-Object Index -eq 0
If you wish these to run on older versions of PowerShell, then use the older syntax by placing each "test" into a scriptblock:
Get-WMIObject -Class Win32_DiskDrive | Where-Object { $_.DeviceID -eq '\\.\PHYSICALDRIVE0' }

Related

Query the NetAdapter on Multiple Machines

#Listing machine from which we will Query
$Machines = Get-ADComputer -Filter * -SearchBase 'OU=Laptops,OU=Win10Modern,OU=LN,OU=Workstations,DC=cooley,DC=com' | Select-Object Name
#Getting the Network Adapter version for Wi-Fi Adapter
ForEach ($Machine in $Machines) {
Get-NetAdapter | Select-Object Name,InterfaceDescription,DriverVersion,DriverDate,DriverProvider
}
Currently, your code loops over objects in variable $Machines, where each object has a single property called Name.
In order to get just the name values, either use Select-Object -ExpandProperty Name or get the array of names like this:
# get an array of computernames
$Machines = (Get-ADComputer -Filter * -SearchBase 'OU=Laptops,OU=Win10Modern,OU=LN,OU=Workstations,DC=cooley,DC=com').Name
Next loop over these computernames and have each computer run the Get-NetAdapter cmdlet:
# capture the output(s) in variable $result
$result = foreach ($Machine in $Machines) {
if (Test-Connection -ComputerName $Machine -Count 1 -Quiet) {
Invoke-Command -ComputerName $Machine -ScriptBlock {
Get-NetAdapter | Select-Object SystemName,Name,InterfaceDescription,
DriverVersion,DriverDate,DriverProvider,Status,AdminStatus
}
}
else {
Write-Warning "Computer '$Machine' does not respond"
}
}
# output on screen
$result
# or to GridView
$result | Out-GridView -Title 'NetAdapterInfo'
# or to CSV file
$result | Export-Csv -Path 'X:\NetAdapterInfo.csv' -NoTypeInformation
AdminStatus is a setting (enabled --> 'up'; disabled --> 'down')
Status is operational status (connected --> 'up'; disconnected --> 'down')
I don't think you can use Get-NetAdapter to connect to remote computers.
You can however use Get-WmiObject Win32_NetworkAdapter -ComputerName .
Like this:
ForEach ($Machine in $Machines) {
Get-WmiObject -Class Win32_NetworkAdapter -Filter "NetConnectionStatus = 2" -ComputerName $Machine
}
You need to become familiar with the properties of the Win32_NetworkAdapter class. You can see all of the properties by running this command:
Get-WmiObject -Class Win32_NetworkAdapter -ComputerName "Localhost" | fl * -Force
or you can use this command to see all of the properties (and methods) available to you.
Get-WmiObject -Class Win32_NetworkAdapter -ComputerName "Localhost" | Get-Member
Most computers will have more than 1 network card (some are hidden) and you have to filter the irrelevant ones out.

CASE, IFElse, or SWITCH Powershell to change output of Get-WmiObject

I have the following code that works as a stand-alone query:
$Type = (Invoke-Command -ComputerName $Computer -ScriptBlock { Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer })
switch -regex ($Type)
{
"VMw.+" {"VM"}
default {"Physical"}
}
I want to add the switch command within the Invoke command instead of a variable (dropping the $Type variable) so that it can be run against multiple computers, how can this be accomplished, I am not determined to use Switch to accomplish the end result?
Get-WmiObject has a ComputerName property so you don't need to use Invoke-Command
switch -regex (Get-WmiObject -ComputerName $Computer -Class Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer)
{
"VMw.+" {"VM"}
default {"Physical"}
}
And by wrapping it in a simple foreach loop you can easily run it against multiple computers:
$Computers = "computer1","computer3","computer3"
foreach ($Computer in $Computers) {
switch -regex (Get-WmiObject -ComputerName $Computer -Class Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer)
{
"VMw.+" {Write-Output "$Computer is a VM Computer"}
default {Write-Output "$Computer is a Physical Computer"}
}
}

letter of first logical disk (PowerShell)

How can I get a letter of first logical disk in PowerShell? I need to assign it to the variable.
So far I have:
$drive = Get-WmiObject -Class win32_volume
If you actually want logical disk information you should query win32_logicaldisk
Get-WmiObject win32_logicaldisk -filter "Drivetype=3"
3 being the Local Disk
If you only wanted the "first" you could pipe it into Select-Object
Get-WmiObject win32_logicaldisk -filter "Drivetype=3" | Select-Object -First 1
If you then still needed information from win32_volume you could do this
$firstDisk = Get-WmiObject win32_logicaldisk -filter "Drivetype=3" | Select-Object -First 1 -ExpandProperty caption
Get-WmiObject -Class win32_volume | Where-Object{$_.DriveLetter -eq $firstDisk}
Use this command:
Get-WmiObject win32_logicaldisk -ComputerName $pc -filter "Drivetype=3"
Depends what else you want to use it with of course, it should give you what you're looking for
Just for funs sake here is another proposal:
Get-PSDrive -PSProvider FileSystem | where {$_.Used -ne $null} | select -First 1
MattĀ“s answer is the way to go though

PowerShell - Select-Object from Win32_OperatingSystem displays rather oddly

First time poster here, I'm a bit of a beginner and I've been keen to get my PowerShell scripting skills up to scratch and I'm come across something rather confusing...
I've made a script to query a collection of computers and I want to query Win32_OperatingSystem but only extrapolate the Build number so I can populate my PSObject with it. I'm trying to add some If logic so that if the build number is 7601, I can write a message under my OS column.
The problem I'm having is that the BuildNumber values are coming out as #{BuildNumber=7601} instead of 7601 for instance. That, and my If statement is borked.
$Machines = Get-Content .\Computers.txt
Foreach($Machine in $Machines)
{
$sweet = (Get-WmiObject -Class Win32_OperatingSystem -computer $Machine | Select-Object BuildNumber)
$dversion = if ($sweet -eq "#{BuildNumber=7601}") {Yes!} else {"Nooooo!"}
New-Object PSObject -Property #{
ComputerName = $Machine
Sweet = $sweet
OS = $dversion
}
}
The issue is that the Get-WMIObject cmdlet is returning a Hash Table. Then the Select-Object is returning just the BuildNumber section you want, the BuildNumber property and it's value. You need to add the -ExpandProperty parameter to only get the value back, not the name/value pair.
Get-WMIObject -Class Win32_OperatingSystem | Select-Object BuildNumber
Returns
#{BuildNumber=7601}
With ExpandProperty
Get-WMIObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber
Returns
7601
Just another option with a ping test to skip unavailable machines.
Get-Content .\Computers.txt | Where-Object {Test-Connection -ComputerName $_ -Count 1 -Quiet} | Foreach-Object {
$sweet = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $_ | Select-Object -ExpandProperty BuildNumber
New-Object PSObject -Property #{
ComputerName = $_.__SERVER
Sweet = $sweet
OS = if ($sweet -eq 7601) {'Yes!'} else {'Nooooo!'}
}
}

Querying partitions/drives on a remote server with WMI

I do the following to check for local drives/partitions on a remote computer:
Get-WmiObject -Class Win32_Share -ComputerName SERVERNAME -Filter "Description='Default share'"
but the command also returns CD-roms etc.
Is there a command to only return disk/partitions?
Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" |
Foreach-Object {$_.DeviceID}
Try this:
Get-WMIObject Win32_DiskPartition -computername remotecomp |
ForEach-Object {
$info = #{}
$info.Disk = $_.DiskIndex
$info.Partition = $_.Index
$info.DriveLetter = $_.psbase.GetRelated('Win32_LogicalDisk') |
Select-Object -ExpandProperty DeviceID
New-Object PSObject -Property $info
}
$info # contains partions number and unit letter as hashtable
Get-WmiObject -query "Select * from Win32_DiskPartition" ... maybe?