Is it possible to do this powershell script in plane old wmic commands? I need to get disk model info based off a path or drive letter if possible but am having issues running powershell scripts.
Get-WmiObject Win32_DiskDrive | % {
$disk = $_
$partitions = "ASSOCIATORS OF " +
"{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " +
"WHERE AssocClass = Win32_DiskDriveToDiskPartition"
Get-WmiObject -Query $partitions | % {
$partition = $_
$drives = "ASSOCIATORS OF " +
"{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " +
"WHERE AssocClass = Win32_LogicalDiskToPartition"
Get-WmiObject -Query $drives | % {
New-Object -Type PSCustomObject -Property #{
Disk = $disk.DeviceID
DiskSize = $disk.Size
DiskModel = $disk.Model
Partition = $partition.Name
RawSize = $partition.Size
DriveLetter = $_.DeviceID
VolumeName = $_.VolumeName
Size = $_.Size
FreeSpace = $_.FreeSpace
}
}
}
}
Script was shared in this question:
Combine `Get-Disk` info and `LogicalDisk` info in PowerShell?
I'm not sure I understand:
wmic is for making single, simple queries.
If you want to make more sophisticated queries (for example, the nested loops above), you're going to need some kind of "programming language". Like C#, VBScript ... or Powershell.
Q: What exactly are the "problems" you've encountered trying to execute this script?
Here is sample output from your script:
d:\>powershell -ExecutionPolicy ByPass -File tmp.ps1
DiskSize : 128034708480
RawSize : 117894545408
FreeSpace : 44036825088
Disk : \\.\PHYSICALDRIVE1
DriveLetter : C:
DiskModel : SanDisk SD6SF1M128G
VolumeName : OS_Install
Size : 117894541312
Partition : Disk #1, Partition #2
DiskSize : 320070320640
RawSize : 320070836224
FreeSpace : 29038071808
Disk : \\.\PHYSICALDRIVE2
DriveLetter : E:
DiskModel : TOSHIBA External USB 3.0 USB Device
VolumeName : TOSHIBA EXT
Size : 320070832128
Partition : Disk #2, Partition #0
DiskSize : 1000202273280
RawSize : 734673240064
FreeSpace : 141853818880
Disk : \\.\PHYSICALDRIVE0
DriveLetter : D:
DiskModel : HGST HTS721010A9E630
VolumeName : Data
Size : 734673235968
Partition : Disk #0, Partition #0
PS:
See also PowerShell says "execution of scripts is disabled on this system."
Related
I'm trying to get my universal uninstaller working. Here is my code:
CLS
$Software = "Zoom"
$Filter = "*" + $Software + "*"
$Program = $ProgUninstall = $FileUninstaller = $FileArg = $NULL
try
{
if (Test-Path -Path "HKLM:\SOFTWARE\WOW6432Node")
{
$programs = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
}
$programs += Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
$programs += Get-ItemProperty -Path "Registry::\HKEY_USERS\*\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue
}
catch
{
Write-Error $_
break
}
foreach($Program in $Programs)
{
$ProgDisplayName = $Program.DisplayName
$ProgUninstall = $Program.UninstallString
if($ProgDisplayName -like $Filter)
{
#$Program
$aux = $ProgUninstall -split #('\.exe'),2,[System.StringSplitOptions]::None
$Uninstaller = (cmd /c echo $($aux[0].TrimStart('"').TrimStart("'") + '.exe')).Trim('"')
$UninsParams = $aux[1].TrimStart('"').TrimStart("'").Trim().split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)
if($aux -notlike "param 0 = *")
{
# $UninsParams = $aux[1].TrimStart('"').TrimStart("'").Trim().split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)
}
$Uninstaller
$UninsParams
# . $Uninstaller $UninsParams | Where-Object { $_ -notlike "param 0 = *" }
}
}
In my example I'm trying to get an output for Zoom. I have the Zoom client installed and the Zoom Outlook plugin installed.
Here is the output of the program:
DisplayName : Zoom Outlook Plugin
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{0B76DE11-5937-4491-A66A-617E42170AFF}
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
PSChildName : {0B76DE11-5937-4491-A66A-617E42170AFF}
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
You cannot call a method on a null-valued expression.
At line:34 char:9
+ $UninsParams = $aux[1].TrimStart('"').TrimStart("'").Trim().s ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
AuthorizedCDFPrefix :
Comments : Zoom
Contact : Zoom Video Communications, Inc.
DisplayVersion : 5.4.58891
HelpLink : https://support.zoom.us/home
HelpTelephone :
InstallDate : 20201119
InstallLocation :
InstallSource : C:\temp\Zoom\
ModifyPath : MsiExec.exe /X{3109C49B-F5E4-4FEC-8F6F-EC5E4626B361}
NoModify : 1
Publisher : Zoom
Readme :
Size :
EstimatedSize : 122109
UninstallString : MsiExec.exe /X{3109C49B-F5E4-4FEC-8F6F-EC5E4626B361}
URLInfoAbout : https://zoom.us
URLUpdateInfo :
VersionMajor : 5
VersionMinor : 4
WindowsInstaller : 1
Version : 84207115
Language : 1033
DisplayName : Zoom
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{3109C49B-F5E4-4FEC-8F6F-EC5E4626B36
1}
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
PSChildName : {3109C49B-F5E4-4FEC-8F6F-EC5E4626B361}
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Part of the problem from what I can tell is the Zoom Outlook plugin doesn't have any uninstall strings associated with it. I'm assuming it's just part of the Zoom Client (even though it's a seperate installer). What I'm trying to do is get this code to work without throwing any errors or displaying false positives.
Here is the output of my 2 parms "$Uninstaller" and "$UninsParams"
You cannot call a method on a null-valued expression.
At line:34 char:9
+ $UninsParams = $aux[1].TrimStart('"').TrimStart("'").Trim().s ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
.exe
/X{3109C49B-F5E4-4FEC-8F6F-EC5E4626B361}
MsiExec.exe
/X{3109C49B-F5E4-4FEC-8F6F-EC5E4626B361}
Thanks in advance!
The problem here is that since the Zoom Client Plugin doesn't have an uninstall script, your -split operation evaluates to a single empty string, and $aux[1] therefore evaluates to $null, hence the error message.
You could filter out entries without a valid UninstallString:
foreach($Program in $Programs |Where-Object UninstallString -match '\.exe')
{
# ... now you don't need to worry about this not resulting in two strings
$aux = $ProgUninstall -split #('\.exe'),2,[System.StringSplitOptions]::None
}
I have been running the following script in the cmd file to get the free disk space of remote servers.It returns size in byte, is there any way to get the size in MB or GB, ideally percentage would be good.
echo off
echo .
echo SERVER-1:
wmic /NODE:"SERVER-1" logicaldisk get size,freespace,caption
echo .
echo .
echo .
echo SERVER-2:
wmic /NODE:"TSERVER-2" logicaldisk get size,freespace,caption
echo .
pause
I would recommend PowerShell rather than wmic in cmd.exe. Short example:
Get-WmiObject Win32_LogicalDisk -ComputerName server-1,server-2 -Filter "DriveType=3" | Select-Object `
#{Name = "ComputerName"; Expression = {$_.__SERVER}},
DeviceID,
#{Name = "Size"; Expression = {$_.Size / 1GB}},
#{Name = "Free"; Expression = {$_.FreeSpace / 1GB}}
This produces output such as the following:
ComputerName DeviceID Size Free
------------ -------- ---- ----
server-1 C: 99.5097618103027 64.3940238952637
server-1 D: 199.873043060303 183.510925292969
server-2 C: 99.5097618103027 64.3940238952637
server-2 D: 199.873043060303 183.510925292969
With help from the Internet I've managed to write a basic PowerShell script that collects hardware info and exports it to a CSV file. It gathers:
Hostname
CPU
NumberOfCores
GPU
RAM
My script still needs to get HDD info (capacity, freespace, id), IPv4 address and MAC.
$Name = hostname
$Motherboard = Get-WmiObject Win32_BaseBoard
$CPU = Get-WmiObject Win32_Processor
$GPU = Get-WmiObject Win32_VideoController
$RAM = Get-WmiObject Win32_ComputerSystem
$To_File = new-object PSObject -property #{
'Name' = $Name
'Motherboard' = $Motherboard.Product
'CPU' = $CPU.Name
'Cores' = $CPU.NumberOfCores
'GPU' = $GPU.Name
'RAM' = "{0:N2}" -f ($RAM.TotalPhysicalMemory/1GB)
}
$To_File | Select-Object Name, Motherboard, CPU, Cores, GPU, RAM |
Export-Csv G:\$Name.csv
Earlier, I also had a line for getting IP and MAC, but it wasn't working universally. It looked like this:
$IP = gwmi Win32_NetworkAdapterConfiguration | Where ($_.DNSDomain -eq 'lan')
$MAC = gwmi Win32_NetworkAdapterConfiguration | Where ($_.DNSDomain -eq 'lan')
Then I would just use in $To_File object 'IP' = $IP.IPAddress and 'MAC' = $MAC.MacAddress
It wasn't good since not all the adapters were named "lan".
For HDD I wrote:
$Disk = Get-WmiObject Win32_LogicalDisk -Filter drivetype=3
$DiskInfo = foreach ($zm in $Disk) {
'ID: ' + $zm.DeviceID
'Capacity: ' + "{0:N2}" -f ($zm.Size/1GB)
'Free Space: ' + "{0:N2}" -f ($zm.FreeSpace/1GB)
}
Since some computers had more than one HDD but I didn't know how I can join these two things together so I could have all that info above and HDD's in one file.
I can't do all that stuff remotely, so the script is on a USB drive and I go to each computer and run it by myself. I still have to do around 20 machines.
I'd also like to know how I can add new rows to an existing CSV file because having 15 CSVs and 'merging' them together is painfull.
Use the -append command with your export-csv command in order add new rows with the existing rows. Your command would look like
$To_File | Select-Object Name, Motherboard, CPU, Cores, GPU, RAM |
Export-Csv G:\$Name.csv -NoTypeInformation -Append
Powershell - Export-CSV and Append link will be helpful to you I guess.
From time to time it happens that no temperature sensors are displayed. I use Powershell to read the values and that works often. I would like to know why Windows sometimes does not return anything. Is that on my laptop, software or what?
powershell Get-WmiObject -Class Win32_PerfFormattedData_Counters_ThermalZoneInformation |Select-Object Name,Temperature
The actual class is MSAcpi_ThermalZoneTemperature. Use the below function:
function Get-Temperature {
$t = Get-WmiObject MSAcpi_ThermalZoneTemperature -Namespace "root/wmi"
$currentTempKelvin = $t.CurrentTemperature / 10
$currentTempCelsius = $currentTempKelvin - 273.15
$currentTempFahrenheit = (9/5) * $currentTempCelsius + 32
return $currentTempCelsius.ToString() + " C : " + $currentTempFahrenheit.ToString() + " F : " + $currentTempKelvin + "K"
}
Alternative:
$strComputer = "."
$objWMi = get-wmiobject -namespace root\WMI -computername localhost -Query "Select * from MSAcpi_ThermalZoneTemperature"
foreach ($obj in $objWmi)
{
write-host "Active:" $obj.Active
write-host "ActiveTripPoint:" $obj.ActiveTripPoint
write-host "ActiveTripPointCount:" $obj.ActiveTripPointCount
write-host "CriticalTripPoint:" $obj.CriticalTripPoint
write-host "CurrentTemperature:" $obj.CurrentTemperature
write-host "InstanceName:" $obj.InstanceName
write-host "PassiveTripPoint:" $obj.PassiveTripPoint
write-host "Reserved:" $obj.Reserved
write-host "SamplingPeriod:" $obj.SamplingPeriod
write-host "ThermalConstant1:" $obj.ThermalConstant1
write-host "ThermalConstant2:" $obj.ThermalConstant2
write-host "ThermalStamp:" $obj.ThermalStamp
write-host
write-host "########"
write-host
}
Reference link : Thermal Zone Info
Hope it helps.
For some reason windows doesn't always return the CPU value for MSAcpi_ThermalZoneTemperature an alternative is to use Open Hardware Monitor Report
Get CPU temperature in CMD/POWER Shell
powershell Get-CimInstance Win32_PerfFormattedData_Counters_ThermalZoneInformation | findstr /i "Name Temperature"
Windows don't "return" value because OEM decided their sensors won't cooperate with windows wmi(in short).
Start > Run or WinKey+R
wmimgmt.msc (and then press [Enter])
PS. - cmd
wmic /namespace:\\root\wmi PATH MSAcpi
I am trying to get these 3 counters thru PowerShell, could you help? Something like below:
Hostname1 : CPU% : 75%
Hostname1 : MEM% : 55%
Hostname1 : Disk1 % : 15%
Hostname1 : Disk2 % : 10%
Hostname1 : Disk3 % : 13%
Hostname1 : Disk4 % : 12%
Hostname2 : CPU% : 75%
Hostname2 : MEM% : 55%
Hostname2 : Disk1 % : 11%
Hostname2 : Disk2 % : 15%
Hostname2 : Disk3 % : 15%
Note: I could not find a counter for %used/memory so I am not going thru performance counters.
Likely your easiest method is using WMI. The below is a script I wrote up for you to demonstrate the ability.
You would need to work on the formatting and I left out disk stats - so some work required.
# Lets import our list of computers
$computers = get-Content .\computer-list.txt
# computer-list.txt is your hostnames each on a new line
# Lets create our variables
$HostInfo = #()
# Lets loop through our computer list from computers
foreach ($computer in $computers) {
# Lets get our stats
# Lets create a re-usable WMI method for CPU stats
$ProcessorStats = Get-WmiObject win32_processor -computer $computer
$ComputerCpu = $ProcessorStats.LoadPercentage
# Lets create a re-usable WMI method for memory stats
$OperatingSystem = Get-WmiObject win32_OperatingSystem -computer $computer
# Lets grab the free memory
$FreeMemory = $OperatingSystem.FreePhysicalMemory
# Lets grab the total memory
$TotalMemory = $OperatingSystem.TotalVisibleMemorySize
# Lets do some math for percent
$MemoryUsed = ($FreeMemory/ $TotalMemory) * 100
$PercentMemoryUsed = "{0:N2}" -f $MemoryUsed
# Lets throw them into an object for outputting
$objHostInfo = New-Object System.Object
$objHostInfo | Add-Member -MemberType NoteProperty -Name Name -Value $computer
$objHostInfo | Add-Member -MemberType NoteProperty -Name CPULoadPercent -Value $ComputerCpu
$objHostInfo | Add-Member -MemberType NoteProperty -Name MemoryUsedPercent -Value $PercentMemoryUsed
# Lets dump our info into an array
$HostInfo += $objHostInfo
}
# Lets output to the console
$HostInfo
This works:
$system = Get-WmiObject win32_OperatingSystem
$totalPhysicalMem = $system.TotalVisibleMemorySize
$freePhysicalMem = $system.FreePhysicalMemory
$usedPhysicalMem = $totalPhysicalMem - $freePhysicalMem
$usedPhysicalMemPct = [math]::Round(($usedPhysicalMem / $totalPhysicalMem) * 100,1)
$driveLetters = Get-WmiObject Win32_Volume | select DriveLetter
foreach ($driveLetter in $driveLetters)
{
$drive = Get-WmiObject Win32_Volume | where {$_.DriveLetter -eq $driveLetter.DriveLetter}
$usedDiskSpace = $drive.Capacity - $drive.FreeSpace
$usedDiskSpacePct = [math]::Round(($usedDiskSpace / $drive.Capacity) * 100,1)
}