Recently I was tasked with finding out which machines have outdated OS versions. For active directory domain joined windows machines this was a very simple task as we could get the information from Active Directory.
For Linux machines, although some were joined to AD, this task was hard as tools like ansible and octopus did not manage all the machines we needed to check so we still needed an alternate solution.
I thought that one way of solving this would be to get the details from vCenter. Most of the servers were virtual machines, but the Guest Operating system column was very vague. The column would include CentOS 4/5/6/7 (64-bit), Other Linux or Ubuntu Linux for example.
So with the limited knowledge I have on Linux I decided to make a PowerShell script which would connect to hosts, provided in a list, via SSH and check the contents of /etc/centos-release or etc/os-release, depending on the OS type, and saves the output in a different file.
The SSH Connection is done using the PowerShell module – POSH-SSH.
The hosts file just needs to contain a list of the FQDN or IP address of the machines you want to obtain the information on.
The module can be installed using the command Install-Module -Name Posh-SSH
This turned out pretty good as it met our requirements so I decided to do a quick post to share it maybe someone else would need it or a customized version of it.
#Script Created by Brian Farrugia 2023 - Feel free to use and modify.
#The Script Uses the module POSH-SSH . Can install it using the PS command "Install-Module Posh-SSH"
#Imports the server list from a text file with a column of just the hostname
#Attempts to connect to each server and saves the output in a CSV File
$SSH_Creds = Get-Credential #SSH Credentials
$SSH_Hosts=Get-Content "C:\Temp\hosts.csv" # Source List
$OutFile="c:\Temp\hosts_output.csv" #Destination Path
#Creating an Object for Connection Failures
$NoSSH_Host=[pscustomobject]@{
'Host'=""
'Output'=""
}
foreach ($SSH_Host in $SSH_Hosts){
#Check if the SSH Session has been established
TRY{
$SSH_Session = New-SSHSession -ComputerName $SSH_Host -Credential $SSH_Creds -AcceptKey -ErrorAction Stop
$SSH_SessionStream = New-SSHShellStream -SSHSession $SSH_Session -TerminalName tty
} CATCH {
#Show Warning of Connection Fails and set connection variables as false
Write-Warning -Message "Could not Connect to $SSH_Host"
$SSH_Session = $false
$SSH_SessionStream = $false
}
#IF the connection was successful get version and save to csv
If ($SSH_Session) {
Write-Host "Connected to Host - $SSH_Host"
$SSH_OSVersion = Invoke-SSHCommand -SSHSession $SSH_Session -Command "if test -f /etc/centos-release ; then cat /etc/centos-release; else cat /etc/os-release | grep PRETTY_NAME= ; fi"
#Check if OS is Cents if not REmove extra text from output
if(!($SSH_OSVersion.Output -like "*CentOS*")){
$SSH_OSVersion.Output=$SSH_OSVersion.Output.split('"')[1]
}
$SSH_OSVersion | Select Host,@{l="OSVersion";e={$_.Output -join " "}} | export-csv -Path $OutFile -force -Append -NoTypeInformation
$SSH_SessionStream.close()
$SSH_Session | Remove-SSHSession | Out-Null
}
#If connection was unsuccessful save the details to CSV
else
{
$NoSSH_Host.Host=$SSH_Host
$NoSSH_Host.Output="Could not Connect"
$NoSSH_Host| Select Host,@{l="OSVersion";e={$_.Output -join " "}} | export-csv -Path $OutFile -force -Append -NoTypeInformation
}
}
The script is also available on GitHUB here
As you can assume I tested this only with CentOS and Ubuntu, as per my use case, so I cannot confirm if it will work with other flavours. If you do any modifications to make it work with others, please let us know in the comments section
As with any script, check it well before running it in your environment. I am still human and prone to mistakes.
Hope you find it useful. If you do please leave a comment.