powershell - get-adcomputer & win32_logicaldisk properties - powershell

I am trying to provide a list of servers in our domain that lists 2003 and 2008/r2 servers. Along with this information i would like to give the current status of their individual C Drive "free space" & "size of the disk". The script below runs fine and prints a list of all the correct operating systems - But...
The free space and Size are all identical..it gives the first servers drive status and replicates this untill the script finishes. for example the script prints:
serverName1 Windows server 2003 standard deviceid=c freespace=40gb size=12gb
serverName2 Windows server 2008r2 standard deviceid=c freespace=40gb size=12gb
....
serverName100 ..... freespace=40gb size=12gb
Import-Module activedirectory
$2008LogPath = "e:/2008servers.txt"
$2003LogPath = "e:/2003servers.txt"
$servers = get-adcomputer -Filter 'ObjectClass -eq "Computer"' -properties "OperatingSystem"
foreach ($server in $servers) {
if($server.OperatingSystem -match "Windows Server 2008") {
Get-WmiObject win32_logicaldisk | Where-Object {$_.deviceid -match "C"} |
ft $server.name, $server.operatingsystem, deviceid, freespace, size -AutoSize }#Out-File -Append $2008LogPath }
elseif($server.operatingsystem -match "Windows Server 2003") {
Get-WmiObject win32_logicaldisk | Where-Object {$_.deviceid -match "C"} |
ft $server.name, $server.operatingsystem, deviceid, freespace, size -AutoSize }#Out-File -Append $2003LogPath }
}

You'll need to use the -ComputerName parameter of the Get-WmiObject cmdlet, to retrieve information from those remote computers. If you don't specify the -ComputerName parameter, then you're retrieving WMI data from the local computer.
To fix this, change your foreach loop to look like the following:
foreach ($server in $servers) {
if($server.OperatingSystem -match "Windows Server 2008") {
Get-WmiObject -ComputerName $Server.Name -Class win32_logicaldisk | Where-Object {$_.deviceid -match "C"} |
ft $server.name, $server.operatingsystem, deviceid, freespace, size -AutoSize }#Out-File -Append $2008LogPath }
elseif($server.operatingsystem -match "Windows Server 2003") {
Get-WmiObject -ComputerName $Server.Name -Class win32_logicaldisk | Where-Object {$_.deviceid -match "C"} |
ft $server.name, $server.operatingsystem, deviceid, freespace, size -AutoSize }#Out-File -Append $2003LogPath }
}

Related

Query the NetAdapter on Multiple Machines

#Listing machine from which we will Query
$Machines = Get-ADComputer -Filter * -SearchBase 'OU=Laptops,OU=Win10Modern,OU=LN,OU=Workstations,DC=cooley,DC=com' | Select-Object Name
#Getting the Network Adapter version for Wi-Fi Adapter
ForEach ($Machine in $Machines) {
Get-NetAdapter | Select-Object Name,InterfaceDescription,DriverVersion,DriverDate,DriverProvider
}
Currently, your code loops over objects in variable $Machines, where each object has a single property called Name.
In order to get just the name values, either use Select-Object -ExpandProperty Name or get the array of names like this:
# get an array of computernames
$Machines = (Get-ADComputer -Filter * -SearchBase 'OU=Laptops,OU=Win10Modern,OU=LN,OU=Workstations,DC=cooley,DC=com').Name
Next loop over these computernames and have each computer run the Get-NetAdapter cmdlet:
# capture the output(s) in variable $result
$result = foreach ($Machine in $Machines) {
if (Test-Connection -ComputerName $Machine -Count 1 -Quiet) {
Invoke-Command -ComputerName $Machine -ScriptBlock {
Get-NetAdapter | Select-Object SystemName,Name,InterfaceDescription,
DriverVersion,DriverDate,DriverProvider,Status,AdminStatus
}
}
else {
Write-Warning "Computer '$Machine' does not respond"
}
}
# output on screen
$result
# or to GridView
$result | Out-GridView -Title 'NetAdapterInfo'
# or to CSV file
$result | Export-Csv -Path 'X:\NetAdapterInfo.csv' -NoTypeInformation
AdminStatus is a setting (enabled --> 'up'; disabled --> 'down')
Status is operational status (connected --> 'up'; disconnected --> 'down')
I don't think you can use Get-NetAdapter to connect to remote computers.
You can however use Get-WmiObject Win32_NetworkAdapter -ComputerName .
Like this:
ForEach ($Machine in $Machines) {
Get-WmiObject -Class Win32_NetworkAdapter -Filter "NetConnectionStatus = 2" -ComputerName $Machine
}
You need to become familiar with the properties of the Win32_NetworkAdapter class. You can see all of the properties by running this command:
Get-WmiObject -Class Win32_NetworkAdapter -ComputerName "Localhost" | fl * -Force
or you can use this command to see all of the properties (and methods) available to you.
Get-WmiObject -Class Win32_NetworkAdapter -ComputerName "Localhost" | Get-Member
Most computers will have more than 1 network card (some are hidden) and you have to filter the irrelevant ones out.

Looking for pograms on client machines

i got a client who wants to find all of the companys installed programs i wrote a script but i dont want the script show me the same same programs for each comuter every time,i want to see overall installations
$computers = get-adcomputers -filter *
foreach($computer in $computers){
Get-ItemProperty
HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-
Table –AutoSize}
I did not test this, but you can try
$computers = (Get-ADComputer -Filter *).DNSHostName # or use .Name or .CN
$software = Invoke-Command -ComputerName $computers {
Get-ItemProperty -Path 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
$software | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate -Unique |
Format-Table -AutoSize
P.S.1 You need to have admin permissions on all computers to do this
P.S.2 Don't forget there is also HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
Apparently you are running into problems where computers are off-line.
To overcome that, you need to add a loop so you can test if a machine is reachable or not.
$computers = (Get-ADComputer -Filter *).Name # or use .CN
# loop through the collection and (if reachable) get the software list
$result = foreach ($computer in $computers) {
# test if the computer is online
if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
# output the properties you need to get collected in variable $result
Invoke-Command -ComputerName $computer {
Get-ItemProperty -Path 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
} | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
}
else {
Write-Warning "Computer $computer is off-line"
}
}
$software = $result | Select-Object * -Unique
# output to console
$software | Format-Table -AutoSize
# output to CSV file
$software | Export-Csv -Path 'D:\Software.csv' -NoTypeInformation

How to imbricate a command inside another command?

I have the following PowerShell script which allows me to collect information about disks & volumes on Windows servers of the domain where the script is launched:
$ErrorActionPreference = 'SilentlyContinue'
Get-ADComputer -Filter 'OperatingSystem -like "*Server*"' -Properties * |
Select-Object Name |
ForEach-Object {
if (Test-Connection $_.Name -Count 1) {
Get-WmiObject -Class Win32_LogicalDisk -ComputerName $_.Name -Filter "DriveType=3" |
Select-Object PSComputerName, DeviceID,
#{Name="Size /GB";Expression={[math]::Round($($_.Size / 1GB), 2)}},
#{Name="Free /GB";Expression={[math]::Round($($_.Freespace / 1GB), 2)}},
#{Name="Free %";Expression={[math]::Round($($_.Freespace/$_.Size)*100, 1)}}
} else {
Write-Nost $_.Name " Connection Error"
}
} |
sort PSComputerName |
Format-Table -AutoSize
I get the following result:
SRV01 Connection Error
SRV02 Connection Error
PSComputerName DeviceID Size /GB Free /GB Free %
-------------- -------- ------------ --------- -------
SERVER03 C: 125,51 105,59 84,1
SERVER04 C: 24,83 7,38 29,7
SERVER05 E: 14,65 7,36 50,2
SERVER06 C: 49,66 29,28 59
I want to add an additional column with the OS for each server.
I would like this column to be in second position, after the "PSComputerName" column. How can I get this result?
I think I use a nested command by adding a Get-WmiObject Win32_OperatingSystem | Select-Object caption in the Get-WmiObject -Class Win32_LogicalDisk ..., but I don't know which syntax to use and how to imbricate a command in another command.
Don't use -properties *... it's going to retrieve every single populated property which you don't need in this script.
Get-ADComputer has an operatingsystem property.
Not tested:
Get-ADComputer -Filter 'OperatingSystem -like "*Server*"' -Properties OperatingSystem | ForEach-Object {
$OS = $_.OperatingSystem
If (Test-Connection $_.Name -Count 1 -Quiet){
Get-WmiObject -Class win32_logicalDisk -ComputerName $_.Name -Filter "DriveType=3" |
Select-Object pscomputername, #{Name="OS";Expression={$OS}} ,DeviceID,
#{Name="Size /GB";Expression={[math]::Round($($_.size / 1GB), 2)}},
#{Name="Free /GB";Expression={[math]::Round($($_.freespace / 1GB), 2)}},
#{Name="Free %";Expression={[math]::Round($($_.Freespace/$_.Size)*100, 1)}}
}
else {
Write-host $_.Name " Connection Error"
}
} | sort pscomputername | Format-Table -AutoSize

Converting from bytes into gigabytes

I am using following script to get disk space audit in our enterprise environment.
Everything works fine except that I don't know how to get those values presented in GB/MB.
Any idea?
$Computers = Get-Content -Path D:\DISKSPACE_audit\Servers.txt
Get-WmiObject Win32_LogicalDisk -ComputerName $Computers | Where-Object {
$_.DriveType -eq 3
} | Select-Object SystemName,DeviceID,FreeSpace,Size
Divide the value by 1GB (or 1MB):
$Computers = Get-Content "D:\DISKSPACE_audit\Servers.txt"
Get-WmiObject Win32_LogicalDisk -Computer $Computers -Filter 'DriveType = 3' |
Select-Object SystemName, DeviceID,
#{n='FreeSpace';e={[int]($_.FreeSpace/1GB)}},
#{n='Size';e={[int]($_.Size/1GB)}}

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*
"-------------------"
}