📜 ⬆️ ⬇️

Inventory of computers in the domain. Laziness is the engine of progress

All welcome.
Recently, the authorities asked me to think about the issue of collecting information on the configuration of computers in our domain. At first, the request was only on account of memory processors and hard drives. The first thought is to go through the departments and please release the computer for a moment. In the case of 1 computer is not difficult, but if they are 1500. Thoughts were directed towards PowerShell.

First, it was necessary to extract a list of all computers in the domain. In this example, my domain is Test.lan. We import this entire list into the AllComputers.csv file.
To do this, do not forget to add the module HELL for PS. In my workplace, he is registered in the profile, and I advise you to do the same:

import-module activedirectory
get-ADcomputer -Filter * |
Where-Object {$a=$_.name; $_.DistinguishedName -ne "CN=$a,OU=Disable,DC=Test,DC=lan"} |
Sort-Object name | Select-Object name | Export-csv C:\Invent\AllComputers.csv -NoTypeInformation


Here it is necessary to clarify that in my domain there is a Disable folder, where the accounts of all the disabled computers are located. If they are disabled, then what's the point to knock on them. Therefore, we exclude this folder from the search.
')
It is clear to everyone that not all computers that are in the domain are turned on, work, or even have a place to be. By this, before proceeding to the test, we check the connection with it. Of course, you can not do this if you have 100 computers. And if you have 2,000 computers, the loss of time with the number of turned off computers of the order of 800 will eat you a long time. It is also worth remembering immediately the computers to which we do not have access. It also makes no sense to knock on their door.

import-csv c:\Invent\AllComputers.csv | foreach {
$a=$_.name
if ((Test-connection $a -count 2 -quiet) -eq "True")
{
if ((Get-WmiObject -computername $a Win32_OperatingSystem) -eq $null)
{


Many may argue:
“Why such difficulties? Why first make a list and then import it. Isn't it easier right away? ”
I agree, it is easier. But it’s nice to have a list of computers before your eyes. In addition, the list is numbered. And you always know how many computers you have in AD.

For the connection test, I selected cmdlet Test-connection with the -quiet parameter, so that we would not get lines with different information, but simply give the answer: True or False. At what we reduce the number of requests from 2 to 4.
If we knock on a computer with a WMI request, and we don’t have rights to do so, we’ll get a bunch of red lines with errors. So we immediately filter such computers with a trial WMI request.

Any information (probably almost any) can be found out if you get into WMI objects, and PS allows you to do it with a bang. So I immediately went deeper into finding the right WMI objects.
Here you can look at all the classes with their attributes.
Making sure that the computer is online, that we have access to it, we look at its insides:

Write-Host " " -ForeGroundColor Green $a
"" | out-file c:\Invent\Comp\$a.txt
Get-WmiObject -computername $a Win32_OperatingSystem |
select-object csname, caption, Serialnumber, csdVersion |
ft @{Label=" "; Expression={$_.CSname}},
@{label=""; Expression={$_.caption}},
@{label=""; Expression={$_.csdVersion}},
@{label=" "; Expression={$_.SerialNumber}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_ComputerSystemProduct | select-object UUID |
ft UUID -autosize | out-file c:\Invent\Comp\$a.txt -append
"" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_Processor | select-object name, SocketDesignation, Description |
ft @{label=""; Expression={$_.name}},
@{label=""; Expression={$_.SocketDesignation}},
@{label=""; Expression={$_.Description}} -auto -wrap | out-file c:\Invent\Comp\$a.txt -append
" " | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_BaseBoard | select-object Manufacturer, Product, SerialNumber |
ft @{label=""; Expression={$_.manufacturer}},
@{label=""; Expression={$_.Product}},
@{label=" "; Expression={$_.SerialNumber}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
" " | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_DiskDrive | select-object Model, Partitions, Size, interfacetype |
ft @{Label=""; Expression={$_.Model}},
@{Label=" "; Expression={$_.Partitions}},
@{Label=" ()"; Expression={($_.Size/1GB).tostring("F00")}},
@{Label=""; Expression={$_.interfaceType}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
" " | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_LogicalDisk -Filter "DriveType=3" | select-object DeviceID, FileSystem, Size, FreeSpace |
ft @{Label=""; Expression={$_.DeviceID}},
@{Label=" "; Expression={$_.FileSystem}},
@{Label=" ()"; Expression={($_.Size/1GB).tostring("F00")}},
@{Label=" ()"; Expression={($_.FreeSpace/1GB).tostring("F00")}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
" " | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_Physicalmemory | Select-Object capacity, DeviceLocator |
ft @{Label=" ()"; Expression={($_.capacity/1MB).tostring("F00")}},
@{Label=""; Expression={$_.DeviceLocator}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
"" | out-file c:\Invent\Comp\$a.txt -append
Get-WmiObject -computername $a Win32_videoController |
Select-Object name, AdapterRAM, VideoProcessor |
ft @{Label=""; Expression={$_.name}},
@{Label=" ()"; Expression={($_.AdapterRAM/1MB).tostring("F00")}},
@{Label=""; Expression={$_.VideoProcessor}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
" " | out-file c:\Invent\Comp\$a.txt -append
$OS=Get-WmiObject -computername $a Win32_OperatingSystem | foreach {$_.caption}
if ($OS -eq "Microsoft Windows 2000 Professional")
{
Get-WmiObject -computername $a Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=True" |
Select-Object caption,MACaddress |
ft @{Label=""; Expression={$_.caption}},
@{Label="MAC "; Expression={$_.MACAddress}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
}
else
{
Get-WmiObject -computername $a Win32_NetworkAdapter -Filter "NetConnectionStatus>0" |
Select-Object name, AdapterType, MACAddress |
ft @{Label=""; Expression={$_.name}},
@{Label="MAC "; Expression={$_.MACAddress}},
@{Label=""; Expression={$_.AdapterType}} -auto -wrap |
out-file c:\Invent\Comp\$a.txt -append
}
}


All information about the computer falls into a text file.
Here it is worthwhile to pay attention to 2 points.
First, the Write-Host " " -ForeGroundColor Green $a I did exclusively for myself, for it is nice to know what PowerShell is doing at the moment.
Secondly, why we check the OS before checking the network card.
Unfortunately, Windows 2000 does not respond to the Win32_NetworkAdapter request, so we apply the Win32_NetworkAdapterConfiguration request to it. Why not just leave the last one? You can leave it, but the Win32_NetworkAdapter returns an attribute such as Name, when its analog is Caption only. Trifle, but nice.
You can also see that when checking a network card, we check it for operability, otherwise we will get a list of several more cards that you are not currently interested in. Do you need this?

That's basically it.
The script can be customized to your needs.
So now the bosses are unlikely to scare you inventory of computers.

Source: https://habr.com/ru/post/124386/


All Articles