Get Operating System Name (Linux / UNIX / Windows) Using PowerShell

As I manage Oracle and SQL Server databases on both Linux and Windows, I sometimes need to determine the OS type before I work with the host so that I can do things conditionally in PowerShell.

I looked around the Web and could not find a good example of how to get this information except this little gem.

How to check Operating System type with PowerShell

Update on 08-Sep-2015: Jack Vamvas whose code I am referencing has updated his post which shows how to get this info with the good old Get-ADComputer. Thanks. The link is http://www.sqlserver-dba.com/2012/06/how-to-check-operating-system-type-with-powershell.html

All I had to do, is wrap it up nicely so that it is callable by everyone in a pipelined or regular fashion. The samples show how to use it.

At the end of the day all I want is given one or more hostnames, I want it to return one of

  • UNIX
  • Linux
  • Windows

Error Capture

Something that I do want to point out in this example is that it takes one or more computer names from the pipleline and returns the OS information. Let us say one or more computer names were invalid, we do not want the whole operation to fail. We would rather deal with the error on a case by case basis. This example illustrates how to capture the error and return it as part of the output.

Async Processing

I am a big fan of processing things in parallel. If I have a list of 80 computer names to go through for some operation, I would prefer to process things in parallel and aggregate the results. An example in the code also shows how this is done.

The Code:


#Key Source: http://www.sqlserver-dba.com/2012/06/how-to-check-operating-system-type-with-powershell.html

####################### 
<# 
.SYNOPSIS 
    Finds whether a host has Linux, UNIX or Windows OS

.DESCRIPTION 
    
    Given one or more computers, loops thru and gets the OS on each. Defaults to localhost if no computer is specified

    The Test-Connection cmdlet sends Internet Control Message Protocol (ICMP) echo request packets ("pings") to one or more remote computers and returns the echo response replies. You can use this cmdlet to determine whether a particular computer can be contacted across an Internet Protocol (IP) network.

    You can use the parameters of Test-Connection to specify both the sending and receiving computers, to run the command as a background job, to set a timeout and number of pings, and to configure the connection and authentication.

    Unlike the traditional "ping" command, Test-Connection returns a Win32_PingStatus object that you can investigate in Windows PowerShell, but you can use the Quiet parameter to force it to return only a Boolean value.


.INPUTS 
    computer list as pipeline input

.OUTPUTS 
    Computer name + OS name + error details if there were any
        
.EXAMPLE 

    #Check the members available in the result
    Get-OSName | Get-Member

.EXAMPLE 

    #Basic example
    Get-OSName | ft

.EXAMPLE 

    #Get OS information from multiple computers

    'myprodhost','mydevhost','myqahost' | Get-OSName | ft -GroupBy Name -auto

.EXAMPLE 

    #Get OS information from multiple computers - some are bad computer names.

    'MyHost1','mydevhost','myqahost' | Get-OSName


.EXAMPLE 

    #Get OS information from multiple computers (some are bad computer names). Check IsError and Error properties + supresses warning messages

    'MyHost1','mydevhost','myqahost' | Get-OSName -WarningAction silentlyContinue | Where-Object {$_.IsError -eq 'Y'} | Select-Object ComputerName, IsError, Error

    
.EXAMPLE 

    #Depends on: http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0#content
    #Get OS info from multiple computers **** asynchronously *****

    #$servers = Get-Content c:\_dblog\servers.txt    
    $servers = @('mydevhost','myqahost','mylinuxdevhost')
    [ScriptBlock] $sb =
            {
                param
                    (
                        [string] $ComputerName,
                        [string] $BasePath
                    )
                
                #------------------------------------------------------------------------------------------------------------
                #Remember that this script block will run in a separate PowerShell session and anything it needs needs to be imported/dot-sourced!
                #------------------------------------------------------------------------------------------------------------    
                . "$BasePath\PoShLib\Computer\Get-OSName.ps1"
                                
                Get-OSName -ComputerName $ComputerName
            }

     #Build the variable need to splat the parameters (for the other parameters outside the list to iterate thru)
    $params = @{
                    Basepath = Get-PoShBasePath
                }   

    $rtn = Invoke-Async -Set $servers -SetParam ComputerName -Params $params -ScriptBlock $sb -Verbose -Measure:$true -ThreadCount 3
    
    $rtn | select-object -expand output
        

.NOTES 
    Excellent and crisp example of how to get pipleline input + addl. inputs     

Version History 
    Base idea from URL referenced at the very top

.LINK 
    http://www.sqlserver-dba.com/2012/06/how-to-check-operating-system-type-with-powershell.html
#>

function Get-OSName
{
    [CmdletBinding()]
    param 
    (
        [Parameter(Position=0,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [Alias('hostname')]
        [Alias('cn')]
        [string[]]$ComputerName = $env:COMPUTERNAME
    )
    
    BEGIN
    {
    }
    
    PROCESS
    {
        foreach ($computer in $ComputerName)
        {
            try
            {

                $TimeToLive = Test-Connection $ComputerName -Count 1 -ErrorAction Stop | Select-Object -ExpandProperty ResponseTimeToLive

                $OS = Switch($TimeToLive)
                        {
                         {$_ -le 64} {"Linux"; break}
                         {$_ -le 128} {"Windows"; break}
                         {$_ -le 255} {"UNIX"; break}
                        }
                
                $output = New-Object System.Object 
                $output | Add-Member -type NoteProperty -Name 'ComputerName'     -value $computer
                $output | Add-Member -type NoteProperty -Name 'OS'               -value $OS
                $output | Add-Member -type NoteProperty -Name 'IsError'          -value 'N'
                $output | Add-Member -type NoteProperty -Name 'Error'            -value $null

                Write-Output $output


            }
            catch 
            {
                $err = $_.Exception

                $output = New-Object System.Object 
                $output | Add-Member -type NoteProperty -Name 'ComputerName'     -value $computer
                $output | Add-Member -type NoteProperty -Name 'OS'               -value $null
                $output | Add-Member -type NoteProperty -Name 'IsError'          -value 'Y'
                $output | Add-Member -type NoteProperty -Name 'Error'            -value $err
                
                Write-Output $output

                Write-Warning "$computer - $err"
            } 
        }
    }
    
    END {}
}
Advertisements

3 thoughts on “Get Operating System Name (Linux / UNIX / Windows) Using PowerShell

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s