letter of first logical disk (PowerShell) - 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

Related

Not able to format output as CSV [duplicate]

This question already has an answer here:
Get WMI Data From Multiple Computers and Export to CSV
(1 answer)
Closed 3 years ago.
Am not able to convert PS output to CSV format using echo function. I need to collect hardware information about multiple servers and got this script from internet. I modified it to collect only the necessary information such as Computername,HDD space, CPU details and RAM.
Below is my code:
$ArrComputers = "PC17"
Clear-Host
foreach ($Computer in $ArrComputers) {
$computerSystemRam = Get-WmiObject Win32_ComputerSystem -Computer $Computer |
select #{n="Ram";e={[math]::Round($_.TotalPhysicalMemory/1GB,2)}} |
FT -HideTableHeaders -AutoSize
$computerCPU = Get-WmiObject Win32_Processor -Computer $Computer |
select Name |
FT -HideTableHeaders
$computerCPUCores = Get-WmiObject Win32_Processor -Computer $Computer |
select NumberOfLogicalProcessors |
FT -HideTableHeaders -AutoSize
$computerC = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'C:'" -ComputerName $Computer |
select #{n="Size";e={[math]::Round($_.Size/1GB,2)}} |
FT -HideTableHeaders -AutoSize
$computerD = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'D:'" -ComputerName $Computer |
select #{n="Size";e={[math]::Round($_.Size/1GB,2)}} |
FT -HideTableHeaders -AutoSize
$computerE = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'E:'" -ComputerName $Computer |
select #{n="Size";e={[math]::Round($_.Size/1GB,2)}} |
FT -HideTableHeaders -AutoSize
echo $computer,$computerC,$computerD,$computerE,$computerSystemRam,$computerCPU,$computerCPUCores
}
and my output is coming as
PC17
99.9
12
537.11
15.98
Intel(R) Xeon(R) CPU E5-2630 0 # 2.30GHz
12
What I need is to get this outputs as a comma separated value like below
PC17,99.9,12,537.11,15.98,Intel(R) Xeon(R) CPU E5-2630 0 # 2.30GHz,12
so that I can open it in Excel. Please let me know what the problem here is? Or any other alternative solution to so as to get the output as .csv.
Remove the Format-Table, use ExpandProperty and choose the right property from the array,
Also, I used -f to format the csv, see the differences:
foreach ($Computer in $ArrComputers)
{
$computerSystemRam = get-wmiobject Win32_ComputerSystem -Computer $Computer | select #{n="Ram";e={[math]::Round($_.TotalPhysicalMemory/1GB,2)}}
$computerCPU = get-wmiobject Win32_Processor -Computer $Computer | select -ExpandProperty Name
$computerCPUCores = get-wmiobject Win32_Processor -Computer $Computer | select -ExpandProperty NumberOfLogicalProcessors
$computerC = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'C:'" -ComputerName $Computer | select #{n="Size";e={[math]::Round($_.Size/1GB,2)}}
$computerD = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'D:'" -ComputerName $Computer | select #{n="Size";e={[math]::Round($_.Size/1GB,2)}}
$computerE = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID= 'E:'" -ComputerName $Computer | select #{n="Size";e={[math]::Round($_.Size/1GB,2)}}
"{0},{1},{2},{3},{4},{5},{6}" -f $computer,$computerC.Size,$computerD.Size,$computerE.Size,$computerSystemRam.Ram,$computerCPU,$computerCPUCores
}

Getting single, specific drive status using 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' }

Powershell script to get number of Physical CPU's

I tried to get the number of physical CPU's using below script however could not able to get the required resul.
get-wmiobject Win32_ComputerSystem
Is there any command to get Number of Physical CPU's ?
Starting in PowerShell 3.0, Get-WmiObject has been superseded by Get-CimInstance.
Number of physical CPUs (a.k.a. sockets)
#(Get-CimInstance -ClassName Win32_Processor).Count
or:
(Get-CimInstance -ClassName Win32_ComputerSystem).NumberOfProcessors
Number of physical cores
(Get-CimInstance -ClassName Win32_Processor | Measure-Object -Property NumberOfCores -Sum).Sum
Number of logical cores
(Get-CimInstance -ClassName Win32_Processor | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum
or:
(Get-CimInstance -ClassName Win32_ComputerSystem).NumberOfLogicalProcessors
If your're looking for properties always use get-member to list them:
get-wmiobject win32_processor | get-member
This way you can find properties like:
NumberOfCores
NumberOfLogicalProcessors
get-wmiobject win32_processor | select-object NumberOfCores, NumberOfLogicalProcessors
Don Jones in his "Creating HTML Reports in Powershell" Link book achieved it this way:
$cs = Get-WmiObject -class Win32_ComputerSystem
$Sockets=$cs.numberofprocessors
$Cores=$cs.numberoflogicalprocessors
The output on my pc is:
$Sockets
1
$Cores
4
In a single line of code:
$(Get-WmiObject Win32_ComputerSystem).NumberOfProcessors
There are also other parameters which might interest you such as: NumberOfCores and NumberOfEnabledCore.
For retrieving the all the properties you can run
Get-WmiObject Win32_ComputerSystem | Select-Object *
Get-WmiObject Win32_Processor | Select-Object *
For further reference about each parameter you can check:
https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor\
https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-computersystem
Use Get-WmiObject or short gwmi
To get the instances of the Win32_Processor class and then simply count them.
$(gwmi Win32_Processor).count

How to format 1-liner for printing an object property

How can I write a quick 1-liner for write-host'ing an object property (let's say Name)? Here is the object I want to print the Name of ...
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2"
I tried ...
write-host $_.name | Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2"
But this seems to still print all object properties. What can I do to fix this command?
You can use the -ExpandProperty parameter of the Select-Object cmdlet to retrieve just the computer name, then pipe that to Write-Host (formatted as multiple lines for readability):
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2" `
| Select-Object -ExpandProperty 'Name' `
| Write-Host;
Alternatively, use the ForEach-Object cmdlet to get the Name property:
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2" `
| ForEach-Object { $_.Name; } `
| Write-Host;
This is not a one-liner, but another approach similar to what you tried:
$computer = Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2";
Write-Host $computer.Name;
Note that since you only care about the Name property of Win32_ComputerSystem, it's a good idea to communicate that to Get-WmiObject using the -Property parameter so it doesn't bother returning information that will be discarded anyways:
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2" -Property 'Name'
In addition to the answer from BACON, another option is this (needs PowerShell v3 or higher):
Write-Host (Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2").Name

Converting from bytes into gigabytes

I am using following script to get disk space audit in our enterprise environment.
Everything works fine except that I don't know how to get those values presented in GB/MB.
Any idea?
$Computers = Get-Content -Path D:\DISKSPACE_audit\Servers.txt
Get-WmiObject Win32_LogicalDisk -ComputerName $Computers | Where-Object {
$_.DriveType -eq 3
} | Select-Object SystemName,DeviceID,FreeSpace,Size
Divide the value by 1GB (or 1MB):
$Computers = Get-Content "D:\DISKSPACE_audit\Servers.txt"
Get-WmiObject Win32_LogicalDisk -Computer $Computers -Filter 'DriveType = 3' |
Select-Object SystemName, DeviceID,
#{n='FreeSpace';e={[int]($_.FreeSpace/1GB)}},
#{n='Size';e={[int]($_.Size/1GB)}}