Get computer OS version - powershell

This script is working fine to get the OS version. I need to know who to get only Microsoft Windows 10 Pro in the result
$Computers = Get-Content C:\computerlist
Foreach($Computer in $Computers)
{
Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction SilentlyContinue | Select-Object CSName, Caption | sort CSName
}

I'm not sure if I understandy you correctly, but I think you need Where-Object:
$Computers = Get-Content C:\computerlist
Foreach($Computer in $Computers)
{
Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction SilentlyContinue | Select-Object CSName, Caption | where Caption -eq "Microsoft Windows 10 Pro" | sort CSName
}

If you want just the Caption value, use Select-Object -ExpandProperty Caption:
foreach($Computer in $Computers)
{
Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Caption
}

Related

Format output in Powershell

I have a small code in my script that is working well. I'm just annoyed with the output..
My output looks like this:
11.11.111.123
Model
-----
HP ZBook Studio G5
csname : XXXXXXX
LastBootUpTime : 22/Apr/2022 08:10:57
But I want it like this:
IP Address: 11.11.111.123
Model: HP ZBook Studio G5
csname: xxxxx
LastBootUpTime: 22/Apr/2022 08:10:57
This is the script:
Get-WmiObject Win32_NetworkAdapterConfiguration -Computername $pcName |
Where { $_.IPAddress } |
Select -Expand IPAddress |
Where { $_ -like '10.11*' -or $_ -like '10.12*'}
Get-WmiObject -Class Win32_ComputerSystem -Computername $pcName | Select Model
Get-WmiObject win32_operatingsystem -Computername $pcName -ea stop | select csname, #{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}} | format-list
Since the output is produced by 3 different classes the way around it is create a new object to merge them:
$IPs = Get-CimInstance Win32_NetworkAdapterConfiguration -ComputerName $pcName |
Where-Object { $_.IPAddress -like '10.11*' -or $_.IPAddress -like '10.12*' }
$Model = (Get-CimInstance -Class Win32_ComputerSystem -ComputerName $pcName).Model
$OS = Get-CimInstance win32_operatingsystem -EA Stop -ComputerName $pcName
[pscustomobject]#{
'IP Address' = $IPs.IpAddress -join ', '
Model = $Model
csname = $OS.CSName
LastBootUpTime = $OS.LastBootUpTime.ToString()
}

Variable is array instead of string?

I wrote this small script and when I test Write-Host $serial it appears fine, but when it is running in the background $serial seems to contain an array.
It tries to rename computer to C000#{SerialNumber=F7ZL3F2} instead of just C000F7ZL3F2.
What should I do to just get string not this array?
Import-Module ActiveDirectory
Get-ADComputer -Filter {Name -like 'DESKTOP-*'} -Properties * | Select Name, DNSHostName | ForEach-Object {
$rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet
if ($rtn -match 'True') {
$serial = Get-WMIObject Win32_Bios -ComputerName $_.name | Select-String SerialNumber
$serial = "C000$serial"
// Write-Host $serial
Rename-Computer -ComputerName $_.name -NewName $serial -DomainCredential $mycreds -Force -Restart
}
}
There are two mistakes to be pointed out in your code -
$serial = Get-WMIObject Win32_Bios -ComputerName $_.name | Select-String SerialNumber
The Select-String cmdlet searches for text and text patterns in input strings and files. Where as the basetype output of Get-WMIObject Win32_Bios is System.Management.ManagementBaseObject
(Get-WMIObject Win32_Bios).Gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True ManagementObject System.Management.ManagementBaseObject
In such cases, instead of Select-String, you can use Select-Object to choose amongst the properties. Since, Serial Number is one of the properties returned by your input command.
$serial = "C000$serial"
The output of $serial will be something like this:
SerialNumber
5CXXXXYYYXZZZ
Again, you can call it directly by $serial.SerialNumber. So your overall code will be
Import-Module ActiveDirectory
Get-ADComputer -Filter {Name -like 'DESKTOP-*'} -Properties * | Select Name, DNSHostName | ForEach-Object {
$rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet
if ($rtn -match 'True') {
$serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
Select-Object SerialNumber
$serial = "C000$($serial.SerialNumber)"
Rename-Computer -ComputerName $_.name -NewName $serial -DomainCredential $mycreds -Force -Restart
}
}
Or you can use -ExpandProperty parameter of the Select-Object cmdlet like
$serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
Select-Object -ExpandProperty SerialNumber
$serial = "C000$serial"
Try changing this line:
$serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
Select-String SerialNumber
to this:
$serial = (Get-WMIObject Win32_Bios -ComputerName $_.name).SerialNumber
or this:
$serial = Get-WMIObject Win32_Bios -ComputerName $_.name |
Select-Object -ExpandProperty SerialNumber
Why are you using Select-String? I would use Select-Object and then -ExpandProperty
Import-Module ActiveDirectory
Get-ADComputer -Filter {Name -like 'DESKTOP-*'} -Properties * | Select Name, DNSHostName | ForEach-Object {
$rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet
if ($rtn -match 'True') {
$serial = Get-WMIObject Win32_Bios -ComputerName $_.name | Select-Object -ExpandProperty SerialNumber
$serial = "C000$serial"
// Write-Host $serial
Rename-Computer -ComputerName $_.name -NewName $serial -DomainCredential $mycreds -Force -Restart
}
}

Ordering Table Columns - Powershell [duplicate]

This question already has answers here:
Change order of columns in the object
(5 answers)
Closed 5 years ago.
Good Afternoon,
I have the following script to generate a table as part of a html report that I have:
(import-csv "C:\AutoTasks\server.txt" |
% {new-object psobject -property #{
"Asset Number"=$_.Computer;
"Region"=$_.Description;
"Online Status"=(test-connection -computername $_.Computer -quiet -count 1);
"Online Since"= Try {(([Management.ManagementDateTimeConverter]::ToDateTime((gwmi Win32_OperatingSystem -ComputerName $_.Computer -ErrorAction Stop).LastBootUpTime)))} Catch {"Offline"} ;
"Service"=((Get-Service -ComputerName $_.Computer | Where-Object {$_.DisplayName -eq "ServiceName"}).Status);
"Disk Size (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2));
"Free Disk Space (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2));
"Free Disk Space %" = ([Math]::Round(100*(([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2)) / ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2))),2))
}} | ConvertTo-HTML -as Table -Fragment -PreContent "<h2>Backup Machines</h2>" | Out-String)
It does everything I need.
However, my issue is with the column ordering. It doesn't display in the column order I've listed, and there is seemingly no logic behind the order it offers.
Any ideas how I can specify the order, am I missing a format-table statement somewhere? My searches are drawing a blank.
In PowerShell 3.0 and newer, you can use the [ordered] attribute on a hashtable literal to indicate that you want an ordered dictionary instead:
(import-csv "C:\AutoTasks\server.txt" |
% {new-object psobject -property $([ordered]#{
"Asset Number"=$_.Computer;
"Region"=$_.Description;
"Online Status"=(test-connection -computername $_.Computer -quiet -count 1);
"Online Since"= Try {(([Management.ManagementDateTimeConverter]::ToDateTime((gwmi Win32_OperatingSystem -ComputerName $_.Computer -ErrorAction Stop).LastBootUpTime)))} Catch {"Offline"} ;
"Service"=((Get-Service -ComputerName $_.Computer | Where-Object {$_.DisplayName -eq "ServiceName"}).Status);
"Disk Size (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2));
"Free Disk Space (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2));
"Free Disk Space %" = ([Math]::Round(100*(([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2)) / ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2))),2))
})} | ConvertTo-HTML -as Table -Fragment -PreContent "<h2>Backup Machines</h2>" | Out-String)

How to store data from foreach function in HTML file in powershell and get Physicall ram

I have written a for each file which stores the BIOS information of the systems in a network and the result is being displayed on my console but I want them to be in a HTML file in an order.
Code:
$arrComputers = get-Content -Path "C:\Computers.txt"
foreach ($strComputer in $arrComputers)
{
$colItems = get-wmiobject -class "Win32_BIOS" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItems)
{
write-host "Computer Name: " $strComputer
write-host "BIOS Version: " $objItem.BIOSVersion
}
$colItems1 = get-wmiobject -class Win32_logicaldisk -Filter "DeviceID = 'C:'" -computername $strComputer
foreach ($objItem1 in $colItems1)
{
$e=$objItem1.freeSpace/1GB
write-host "Total Space: " $e
}
$colItems4 = Get-WMIObject -class Win32_PhysicalMemory -computername $strComputer
$colItems5=$colItems4 | Measure-Object -Property capacity -Sum
foreach ($objItem4 in $colItems5)
{
$e4=$colItems5.Sum/1GB
write-host "Memory : " $e4
}
}
Can you please help me in saving all the above data in HTML
You need to look at the ConvertTo-Html cmdlet.
Get-WmiObject -Class Win32_BIOS -ComputerName localhost,$env:COMPUTERNAME |
Select PSComputerName,Version,SerialNumber |
ConvertTo-Html |
Out-File c:\test3.html
Another method based on OPs update:
$arrComputers = get-Content -Path "C:\Computers.txt"
$arrComputers | ForEach-Object { Get-WMIObject -Class Win32_BIOS -ComputerName $_ } |
Select PSComputerName, Version, Manufacturer |
ConvertTo-Html |
Out-File C:\test4.html

Get-Service on multiple remote machines

I can only get the command to return the services on the first computer in the text file.
Is there a better way than for-each for this task?
Get-Service *vault* -ComputerName (Get-Content c:\users\sean\desktop\js.txt) | select name,status,machinename | sort machinename | format-table -autosize
Try it without the get-content. Try this:
Get-Service *vault* -ComputerName c:\users\sean\desktop\js.txt | select name,status,machinename | sort machinename | format-table -autosize
If that doesn't work, then try:
$Computers = Get-Content c:\users\sean\desktop\js.txt
Get-Service *vault* -computername $Computers | Select name,status,machinename |sort machinename |format-table -autosize
If you are eager for a one-liner then try this:
Get-Content c:\users\sean\desktop\js.txt | Get-Service *vault* | Select name,status,machinename |sort machinename |format-table -autosize
I would try the top one first. I would test, but I don't have access to anything I can do a proper test right now.
$Computers = get-content .\desktop\test.txt
$Service = "Vault"
foreach ($computer in $computers) {
$computer
$Servicestatus = get-service -name $Service -ComputerName $computer
}
$Servicestatus | select-object Name,Status,MachineName | format-table -Autosize
This works for me, it gives me each of the computers in the text file, and it looks for the service.
This is what I use. I get the list of computers from an OU in AD.
Import-Module ActiveDirectory
$ou = "OU=Servers,DC=Domain,DC=com"
$servers = Get-ADComputer -Filter * -SearchBase $ou | select-object -expandproperty name
Foreach ($server in $servers){
$Data = Get-Service -ServiceName *IIS*,*TomCat*,*httpd* -ComputerName $server | select machinename,name | sort machinename | format-table -AutoSize
Write($Data) | Out-File .\WebServices.txt -Append
}
$servers = Get-Content .\servers.txt
Foreach ($server in $servers) {
"$server"
Get-Service -ComputerName $Server -name -like "*vault*"
"-------------------"
}
Following a memory limitation limit with older versions of PowerShell, I was required to refresh my code:
Old code:
gwmi win32_service -computer $allcomputers | Select-Object __SERVER,Name,state,startmode,StartName
New code:
`$servers = Get-Content "computers.txt"
Foreach ($server in $servers) {
Get-WmiObject -Class WIN32_service -ComputerName $server |
Select-Object __SERVER,Name,state,startmode,StartName |
Export-Csv -path "Report.CSV" -NoTypeInformation -Append
}`
This is how you can get list of all services in your AD domain:
Get-ADComputer -Filter {OperatingSystem -Like “Windows 10*”} | ForEach-Object {Get-WmiObject -Class Win32_Service -Computer $_.Name}
More useful examples on this (get list of services for all computer listed in a text file, etc.):
https://www.action1.com/kb/list_of_services_on_remote_computer.html
Get-Service -ComputerName ... has a bug in PowerShell 2.0 that only returns the first computer. This is fixed in newer versions so if you upgrade to PowerShell 3.0 or newer, your original code will work fine.
As a workaround, use a foreach-loop to run Get-Service once for each computer:
Get-Content c:\users\sean\desktop\js.txt |
ForEach-Object { Get-Service -Name *vault* -ComputerName $_ } |
Select-Object -Property Name, Status, MachineName |
Sort-Object -Property MachineName |
Format-Table -AutoSize
Nick's solution totally doesn't work for me. I ended up writing a quick and dirty one that works:
$servers = Get-Content .\servers.txt
Foreach ($server in $servers) {
"$server"
Get-Service *vault*
"-------------------"
}