Getting Hardware Info script trouble - windows

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.

Related

Failing to find DC servers and their disk usage

so i got stuck with this assignment where i need to find all DC servers and their disk ussage
i tried first to get all the DC servers and then add the disk usage info but it doesn't work
$getdomain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
$getdomain | ForEach-Object {$_.DomainControllers} |
ForEach-Object {
$hEntry= [System.Net.Dns]::GetHostByName($_.Name)
New-Object -TypeName PSObject -Property #{
Name = $_.Name
IPAddress = $hEntry.AddressList[0].IPAddressToString
}
} | get-wmiobject -class win32_logicaldisk | select-object pscomputername,deviceid,freespace,size
For the task you have you have some useless code lines in your code. Did you copy the code from somewhere? ;-)
I'd recommend to take your time to start learning the very basics of Powershell first.
That's actually all you need:
$DCList = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain().DomainControllers
foreach ($DC in $DCList) {
Get-CimInstance -ClassName win32_logicaldisk -ComputerName $DC.Name |
Select-Object -Property pscomputername, deviceid, freespace, size
}
Conclusion: You should remove what you have inside the loop from your copied code and replace it with what you have added at the end. ;-)

How to get every disk in Windows and filter on DeviceType and then add the size of the disk next to it, separated by a comma?

I'm writing an PowerShell script to collect some data of a computer. I'm almost done, but I don't know how to get size of all the disks on the computer. I know how to do it with a couple of If statements, but I want it to automatically detect the drives, not that I have to write a new If statement if a new disk is attached. The output I want is as follows: "A:,250GB". The "A:," bit works, but not the disk size bit.
This is the code I used and tweaked, but to no avail:
$Drives = Get-WmiObject Win32_logicaldisk| ?{$_.DriveType -eq 3} | ForEach-Object {$_.name}
ForEach ($Drivename in $Drives) {
$Drivenames = Get-WMIObject -Query "Select * From win32_logicaldisk Where DriveType = '3'" -computer localhost | Select-Object DeviceID
$Drive = [Math]::Round($Drivenames.Size / 1GB)
"$Drivenames,", $Drive | Out-File "C:\HDS\HDS_DRIVES.csv" -Append
}
In addition, [Math]::Round($Drivenames.Size / 1GB) throws me an error:
Method invocation failed because [System.Object[]] does not contain a method named 'op_Division'"
You can use Calculated Property with Select-Object to make it much more simple:
Get-WmiObject Win32_logicaldisk| ? {$_.DriveType -eq 3} |
Select-Object #{N="DeviceId";E={$_.DeviceId}},`
#{N="VolumeName";E={$_.VolumeName}},`
#{N="Size";E={[Math]::Round($_.Size / 1GB)}} |
Out-File "C:\HDS\HDS_DRIVES.csv" -Append
Note that you don't need to Invoke Get-WmiObject Twice like in your example.
Why it doesn't work?
The issue is that $Drivenames contains only DeviceID (as you used Select-Object to get only that property). Therefore you're getting an error where trying to round it (as rounding nothing is not supposed to work).
How to fix it?
You have to add Size and then access it using .PropertyName:
$DriveInfo = Get-WMIObject -Query "Select * From win32_logicaldisk Where DriveType = '3'" -computer localhost | Select-Object DeviceID, Size
$DriveInfo | ForEach-Object {
$DriveSize = [Math]::Round($_.Size / 1GB)
"$($_.DeviceID),$DriveSize" | Out-File "C:\HDS\HDS_DRIVES.csv" -Append
}
How can I make it more elegant
Also, take a look at #Avshalom's answer which uses calculated property.

How to get disk information from computers on Active Directory with Powershell

I have basic knowledge of PowerShell and I have been given a project that needs me to create a PowerShell script that gets all the computers on the domain in active directory and gather the free space/used space of each computer.
This is what I use in order to get servers with low disk space:
Import-Module ActiveDirectory
$Servers = Get-ADcomputer -Filter {OperatingSystem -like "*Server*"} -Properties Name, OperatingSystem -SearchBase "DC=yourDN,DC=local" | Select Name
$diskReport = Foreach($Server in $Servers)
{
#$Status = "Offline"
$Name = $Server.Name
#Make sure server is online
if(Test-Connection -ComputerName $Name -ErrorAction SilentlyContinue)
{
#Get only 10%
Get-WMIObject win32_logicaldisk -ComputerName $Name -Filter "DriveType=3" -ErrorAction SilentlyContinue | Where-Object { ($_.freespace/$_.size) -le '0.1'}
}
else
{
#Server is offline
}
}
$lowservers = $diskreport | Select-Object #{Label = "Server Name";Expression = {$_.SystemName}},
#{Label = "Drive Letter";Expression = {$_.DeviceID}},
#{Label = "Total Capacity (GB)";Expression = {"{0:N1}" -f( $_.Size / 1gb)}},
#{Label = "Free Space (GB)";Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) }},
#{Label = 'Free Space (%)'; Expression = {"{0:P0}" -f ($_.freespace/$_.size)}}
This will first pull all your objects using Get-ADComputer. Then it just does a simple foreach to put everything into $diskReport. The $lowservers is just to clean it up a bit.
You can do whatever you want with $lowservers. I have mine on a scheduled task to run every Monday and Friday. Then send out an email if it finds something low.

Powershell, How to get date of last Windows update install or at least checked for an update?

I am trying to find a way of retrieving the date/time of which the last windows update was either installed, or checked for.
So far I have found a function that allows to list recent Windows Updates, but it is far too much data and too bloated for such a simple function. Secondly I have tried to access the registry although I am having no luck in retriving the value I am after.
I am testing this on a Windows 10 Machine although the software will probably reside on Windows Server 2012 R2.
Here is an example of some of the code I have tried:
$key = “SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\Results\Install”
$keytype = [Microsoft.Win32.RegistryHive]::LocalMachine
$RemoteBase = [Microsoft.Win32.RegistryKey]::OpenBaseKey($keytype,"My Machine")
$regKey = $RemoteBase.OpenSubKey($key)
$KeyValue = $regkey.GetValue(”LastSuccessTime”)
$System = (Get-Date -Format "yyyy-MM-dd hh:mm:ss")
Also, just trying the Get-ChildItem
$hello = Get-ChildItem -Path “hkcu:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\”
foreach ($a in $hello) {
$a
}
I've checked in regedit and this key does not exist. Going to the "Windows Update" path shows only App Updates and not Windows updates.
EDIT
I seem to be closer to my goal with this line:
Get-HotFix | Where {$_.InstallDate -gt 30}
However how to I only retrive those of which have been installed in the last 30 days? And this doesnt show many results, even using Select $_.InstallDate
an option :
gwmi win32_quickfixengineering |sort installedon -desc
Another alternative, using the com object Microsoft.Update.Session can be find here : https://p0w3rsh3ll.wordpress.com/2012/10/25/getting-windows-updates-installation-history/
in short :
$Session = New-Object -ComObject Microsoft.Update.Session
$Searcher = $Session.CreateUpdateSearcher()
$HistoryCount = $Searcher.GetTotalHistoryCount()
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa386532%28v=vs.85%29.aspx
$Searcher.QueryHistory(0,$HistoryCount) | ForEach-Object {$_}
Here you have how to know the date and time of the last Windows update in a single line of Powershell:
(New-Object -com "Microsoft.Update.AutoUpdate"). Results | fl
You also have the following script to check it massively in Windows Server:
$ servers = Get-ADComputer -Filter {(OperatingSystem-like "* windows * server *") -and (Enabled -eq "True")} -Properties OperatingSystem | Sort Name | select -Unique Name
foreach ($ server in $ servers) {
write-host $ server.Name
Invoke-Command -ComputerName $ server.Name -ScriptBlock {
(New-Object -com "Microsoft.Update.AutoUpdate"). Results}
}
Extracted from: https://www.sysadmit.com/2019/03/windows-update-ver-fecha-powershell.html
Get-HotFix |?{$_.InstalledOn -gt ((Get-Date).AddDays(-30))}
Using PowerShell, you can get the date of the las Windows update like this:
$lastWindowsUpdate = (Get-Hotfix | Sort-Object -Property InstalledOn -Descending | Select-Object -First 1).InstalledOn

Script to identify Process Name , Memory , Account Owner in Windows server

I am running a web service in Windows machine , and i wanted to know the Memory used by each user while accessing this Web service.
In Task Manager I could see the ProcessName, UserName, Memory.
Is there a way to get the same by running powershell or batch script?
Please help.
There's may be a cleaner way to do this, but here's an example:
$users = #{}
$process = Get-Process
Get-WmiObject Win32_SessionProcess | ForEach-Object {
$userid = (($_.Antecedent -split “=”)[-1] -replace '"' -replace “}”,“”).Trim()
if($users.ContainsKey($userid))
{
#Get username from cache
$username = $users[$userid]
}
else
{
$username = (Get-WmiObject -Query "ASSOCIATORS OF {Win32_LogonSession.LogonId='$userid'} WHERE ResultClass=Win32_UserAccount").Name
#Cache username
$users[$userid] = $username
}
$procid = (($_.Dependent -split “=”)[-1] -replace '"' -replace “}”,“”).Trim()
$proc = $process | Where-Object { $_.Id -eq $procid }
New-Object psobject -Property #{
UserName = $username
ProcessName = $proc.Name
"WorkingSet(MB)" = $proc.WorkingSet / 1MB
}
}
OUTPUT:
UserName ProcessName WorkingSet(MB)
-------- ----------- --------------
Frode taskhostex 61,5
Frode explorer 172,33203125
Frode RuntimeBroker 21,9375
Frode HsMgr 5,578125
Frode HsMgr64 5,453125
Frode SetPoint 17,4375
The code needs to run as admin to get sessions for other users(not just the current user).
Have you tried get-process?
You can run that and filter by various factors. You can use -name or -id to filter by process name or PID. ex:
get-process -name iexplore
get-process -Id 0 # this returns the idle process.
Or, you can filter by other factors
Get processes using more than 1MB of memory
get-process |Where-object {$_.WorkingSet64 -gt 1048576}
More info on get-process here: http://technet.microsoft.com/en-us/library/ee176855.aspx

Resources