How to format 1-liner for printing an object property - powershell

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

Related

Writing variable value only in Powershell

I'm trying to collect 4 values into variables, then write those values to the screen so it would look like this:
value1,value2,value3,value4
Instead, I'm getting the following:
#{name=value1},#{domain=value2},#{domainrole=value3},#{workgroup=value3}
Here's my code. Any feedback will be most appreciated. Thanks.
$name = Get-CimInstance -ClassName Win32_ComputerSystem | select name
$domain = Get-CimInstance -ClassName Win32_ComputerSystem | select domain
$domainrole = Get-CimInstance -ClassName Win32_ComputerSystem | select domainrole
$workgroup = Get-CimInstance -ClassName Win32_ComputerSystem | select workgroup
write-host "$name,$domain,$domainrole,$workgroup"
You have some options to achieve this. One would be to use the parameter -ExpandProperty of Select-Object to turn objects with properties in string ... like this:
$name = Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty name
$domain = Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty domain
$domainrole = Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty domainrole
$workgroup = Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty workgroup
"$name,$domain,$domainrole,$workgroup"
Or you could keep the objects and acces their properties with the dot notation:
$name = Get-CimInstance -ClassName Win32_ComputerSystem
$domain = Get-CimInstance -ClassName Win32_ComputerSystem
$domainrole = Get-CimInstance -ClassName Win32_ComputerSystem
$workgroup = Get-CimInstance -ClassName Win32_ComputerSystem
"$name.name,$domain.domain,$domainrole.domainrole,$workgroup.workgroup"
I'd recommend the latter one because you can still use the objects for further steps in your code without loosing their properties. ;-)
This is a very command question. I like using foreach-object or % for short:
[pscustomobject]#{name='joe'} | % name
joe

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
}

Cannot match if condition

Basically, I'm trying to read a BIOS setting and then with the if condition, if it matches to execute another command.
It works fine with other variables, it is just with this one.
#This Script will check for VT and VTD on Lenovo machines and enable them
#if the current value is disabled.
#Run Set-ExecutionPolicy Unrestricted first.
#Run As administrator
#Check the current values
$VT= gwmi -class Lenovo_BiosSetting -namespace root\wmi |
Where-Object {$_.CurrentSetting.split(",",[StringSplitOptions]::RemoveEmptyEntries) -eq "VirtualizationTechnology"} |
Format-List CurrentSetting
$VTD= gwmi -class Lenovo_BiosSetting -namespace root\wmi |
Where-Object {$_.CurrentSetting.split(",",[StringSplitOptions]::RemoveEmptyEntries) -eq "VTdFeature"} |
Format-List CurrentSetting
#Modify the values
#$EnabledVT= (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting("VirtualizationTechnology,Enable")
#$EnableVTD= (gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting("VTdFeature,Enable")
#$SaveBios=(gwmi -class Lenovo_SaveBiosSettings -namespace root\wmi).SaveBiosSettings()
#Check if VT is disabled and enable it if it is.
Echo "Virtualization current settings are below"
Write-output $VT
IF ($VT -like "*Disable*") {
"this is not working"
} else {
"Setting is already set to enabled, no changes made."
}
#Check if VTD is disabled and enable it if it is.
Write-output $VTD
IF ($VTD -like "*,Disable") {
this is not working
} else {
"Setting is already set to enabled, no changes made."
}
#Save bios settings.
$SaveBios
Write-host "Check completed, Please restart computer for changes to take effect if any changes were made. "
I have tried different conditions to match exactly or the like or the match but nothing seems to be able to find anything.
So, here's the issue that you are having. You are piping the output of your command to Format-List, and storing that info in your variable. Don't do that. The Format-* cmdlets should be used to format things for output to the console, not for storing data for use later. Instead remove that part, and then reference the CurrentSetting property of the object.
$VT= gwmi -class Lenovo_BiosSetting -namespace root\wmi | Where-Object {$_.CurrentSetting.split(“,”,[StringSplitOptions]::RemoveEmptyEntries) -eq “VirtualizationTechnology”}
$VTD= gwmi -class Lenovo_BiosSetting -namespace root\wmi | Where-Object {$_.CurrentSetting.split(“,”,[StringSplitOptions]::RemoveEmptyEntries) -eq “VTdFeature”}
IF ($VT.CurrentSetting -like "*Disable*") {"this is now working"}
else {"Setting is already set to enabled, no changes made."}
This will function as desired.
Instead of Format-List, use Select-Object -ExpandProperty:
$VT = gwmi -class Lenovo_BiosSetting -namespace root\wmi | Where-Object {$_.CurrentSetting.split(“,”,[StringSplitOptions]::RemoveEmptyEntries) -eq “VirtualizationTechnology”} | Select-Object -ExpandProperty CurrentSetting
$VTD = gwmi -class Lenovo_BiosSetting -namespace root\wmi | Where-Object {$_.CurrentSetting.split(“,”,[StringSplitOptions]::RemoveEmptyEntries) -eq “VTdFeature”} | Select-Object -ExpandProperty CurrentSetting

how to amend formatting of output

when I do the below I get the format as "#{xxx}"...how do I just get the computer description and none of the the other formatting around it?
$CompDes = Get-WmiObject -Class Win32_OperatingSystem |Select
Description
Write-Host "Computer Description $CompDes"
Output:
Computer Description #{Description=TESING_SERVER}
Thanks,
$CompDes = Get-WmiObject -Class Win32_OperatingSystem | Select -exp Description
Write-Host "Computer Description $CompDes"
-exp is short for -ExpandProperty. It gets the value of the specified property.
Another way:
$CompDes = Get-WmiObject -Class Win32_OperatingSystem | Foreach-Object {$_.Description}

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?