Gather remote computer system and disk information via script

I am looking for a script to get the server information for a list of servers. The output should be in a CSV format and the output should contain the following columns or Fields:

Server Name, Manufacturer,Model, OS Name, OS Version, Service Pack No. of CPU, Cores, RAM, IP Address, Subnet Mask, Default Gateway, C:\ DiskSpace D:\ Diskspace, Is Cluster Cluster Name

For drives the script should provide the diskspace details for all the drives..... say for example  server A may have C:\ drive, E:\drive and another server B may have C:\ drive, E: \drive and F:\ drive so the output should provide for the C: drive and E: drive diskspace for Server A and for Server B the output should be C:\ drive E: drive and F: drive.

For cluster, if server is part of cluster then the output should provide for Is Cluster field is Yes and for cluster name, the name of the cluster

Thanks
jmohan0302Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Maidine FouadEngineerCommented:
There is an open source Scrip you can Modify to suit your needs , it does most of the pre requesites you required , its output is not csv tough but xls

Il attach it below (the owner has stated in the first lines he has no problem what so ever with the code being modified & used)  :

' Inventory.vbs
' VBScript program to inventory computers in the domain.
'
' ----------------------------------------------------------------------
' Copyright (c) 2004-2010 Richard L. Mueller
' Hilltop Lab web site - http://www.rlmueller.net
' Version 1.0 - February 19, 2004
' Version 1.1 - July 6, 2007 - Modify use of Fields collection of
'                              Recordset object.
' Version 1.2 - July 31, 2007 - Bug fix in Sub InitIE.
' Version 1.3 - January 20, 2010 - List all Hot Fixes.
' Version 1.4 - September 14, 2010 - Modify Ping function for IPv6.
' Version 1.5 - November 6, 2010 - No need to set objects to Nothing.
'
' You have a royalty-free right to use, modify, reproduce, and
' distribute this script file in any way you find useful, provided that
' you agree that the copyright owner above has no warranty, obligations,
' or liability for such use.

Option Explicit

Dim strComputer, strDN
Dim objShell, objFSO, strTemp, strTempFile
Dim objRootDSE, strRootDomain, adoConnection, adoCommand, strQuery
Dim adoRecordset, strAttributes
Dim objRemote, strRole
Dim strExcelPath, objExcel, objSheet, intCol
Dim colSettings, objOS, objComputer
Dim objFix, strFixID
Dim objIE, strIETitle, blnFlag, strPrevious, strStatus

Const ADS_CHASE_REFERRALS_SUBORDINATE = &H20

' Check for required argument.
If (Wscript.Arguments.Count <> 1) Then
    Wscript.Echo "Argument <FileName> required. For example" & vbCrLf _
        & "cscript Inventory.vbs ""c:\MyFolder\Inventory.xls"""
    Wscript.Quit
End If

' Spreadsheet file name to be created.
strExcelPath = Wscript.Arguments(0)

' Set IE display box title. Dashes ("-") are to move the Microsoft title
' appended to the title we specify out of view.
' blnFlag is set to False when the user closes the IE display box.
strIETitle = "Computer Inventory" & String(60, "-")
blnFlag = True

Set objShell = CreateObject("Wscript.Shell")

' Initialize display box with initial message.
InitIE "Program Initializing..."

' Determine DNS domain name from RootDSE object.
On Error Resume Next
Set objRootDSE = GetObject("LDAP://RootDSE")
If (Err.Number <> 0) Then
    On Error GoTo 0
    MsgIE "IE_Quit"
    Wscript.Echo "Domain not found, program aborted."
    Wscript.Echo "You may not be logged into a domain."
    Wscript.Quit
End If
On Error GoTo 0
strRootDomain = objRootDSE.Get("rootDomainNamingContext")

' Bind to Excel.
On Error Resume Next
Set objExcel = CreateObject("Excel.Application")
If (Err.Number <> 0) Then
    On Error GoTo 0
    MsgIE "IE_Quit"
    Wscript.Echo "Excel application not found."
    Wscript.Echo "Program aborted."
    Wscript.Quit
End if
On Error GoTo 0

' Create new workbook.
objExcel.Workbooks.Add

' Bind to worksheet.
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)
objSheet.Name = "Inventory"

' Write row headings.
objSheet.Cells(1, 1).Value = "sAMAccountName"
objSheet.Cells(2, 1).Value = "distinguishedName"
objSheet.Cells(3, 1).Value = "WMI"
objSheet.Cells(4, 1).Value = "# of OS's"
objSheet.Cells(5, 1).Value = "OS Caption"
objSheet.Cells(6, 1).Value = "OS Version"
objSheet.Cells(7, 1).Value = "OS Service Pack"
objSheet.Cells(8, 1).Value = "# of Hot Fixes"
objSheet.Cells(9, 1).Value = "Hot Fix IDs"
objSheet.Cells(10, 1).Value = "# of Computer Systems"
objSheet.Cells(11, 1).Value = "Computer Role"

' Format spreadsheet.
objSheet.Range("A1:A11").Font.Bold = True
objSheet.Select
objSheet.Range("B2").Select
objExcel.ActiveWindow.FreezePanes = True
objExcel.Columns(1).Columnwidth = 18

' Use ADO to search Active Directory for all computers.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open = "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

' Retrieve attributes.
strAttributes = "sAMAccountName,distinguishedName"

strQuery = "<LDAP://" & strRootDomain _
    & ">;(ObjectCategory=computer);" & strAttributes & ";subtree"

adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
adoCommand.Properties("Chase Referrals") = _
    ADS_CHASE_REFERRALS_SUBORDINATE

Set adoRecordset = adoCommand.Execute

Set objFSO = CreateObject("Scripting.FileSystemObject")

' Specify temporary file to save ping results.
strTemp = objShell.ExpandEnvironmentStrings("%TEMP%")
strTempFile = strTemp & "\RunResult.tmp"

' Enumerate computer objects.
intCol = 2
Do Until adoRecordset.EOF
    strComputer = adoRecordset.Fields("sAMAccountName").Value
    ' Remove trailing "$".
    strComputer = Left(strComputer, Len(strComputer) - 1)
    objSheet.Cells(1, intCol).Value = strComputer
    objSheet.Cells(1, intCol).Font.Bold = True
    strDN = adoRecordset.Fields("distinguishedName").Value
    objSheet.Cells(2, intCol).Value = strDN

    If (intCol = 2) Then
        MsgIE "Documenting computer: " & strComputer _
            & vbCrLf & "Previous: none" _
            & vbCrLf & "Total documented: 0" _
            & vbCrLf & "To abort, close this box"
    Else
        MsgIE "Documenting computer: " & strComputer _
            & vbCrLf & "Previous: " & strPrevious & strStatus _
            & vbCrLf & "Total documented: " & (intCol - 2) _
            & vbCrLf & "To abort, close this box"
    End If

    strPrevious = strComputer

    If (blnFlag = False) Then
        ' Save spreadsheet and close the workbook.
        On Error Resume Next
        objExcel.ActiveWorkbook.SaveAs strExcelPath
        If (Err.Number <> 0) Then
            On Error GoTo 0
            Wscript.Echo "Spreadsheet could not be saved as " & strExcelPath
            Wscript.Echo "The path may be invalid."
            strExcelPath = ""
        End If
        On Error GoTo 0
        objExcel.ActiveWorkbook.Close

        ' Quit Excel.
        objExcel.Application.Quit

        ' Clean up.
        adoRecordset.Close
        adoConnection.Close
        If (objFSO.FileExists(strTempfile) = True) Then
            objFSO.DeleteFile(strTempFile)
        End If

        Wscript.Echo "Program Aborted"
        Wscript.Echo "Computers documented: " & (intCol - 1)
        If (strExcelPath <> "") Then
            Wscript.Echo "See spreadsheet " & strExcelPath
        End If
        Wscript.Quit
    End If

    ' Ping computer to see if online.
    If (IsConnectible(strComputer, 1, 750) = True) Then
        ' Connect to computer with WMI.
        On Error Resume Next
        Set objRemote = GetObject("winmgmts:" _
            & "{impersonationLevel=impersonate}!\\" _
            & strComputer & "\root\cimv2")
        If (Err.Number <> 0) Then
            On Error GoTo 0
            objSheet.Cells(3, intCol).Value = "WMI Not Installed"
            strStatus = " no WMI"
        Else
            On Error GoTo 0
            objSheet.Cells(3, intCol).Value = "WMI Installed"
            On Error Resume Next
            Set colSettings = objRemote.ExecQuery _
                ("SELECT * FROM Win32_OperatingSystem")
            If (Err.Number <> 0) Then
                On Error GoTo 0
                  objSheet.Cells(4, intCol).Value = "Failed"
            Else
                On Error GoTo 0
                objSheet.Cells(4, intCol).Value = colSettings.Count
                For Each objOS In colSettings
                    objSheet.Cells(5, intCol).Value = objOS.Caption
                    objSheet.Cells(6, intCol).Value = objOS.Version
                    objSheet.Cells(7, intCol).Value = _
                        objOS.ServicePackMajorVersion & "." _
                        & objOS.ServicePackMinorVersion
                Next
                Set objOS = Nothing
            End If

            If (blnFlag = False) Then
                ' Save spreadsheet and close the workbook.
                On Error Resume Next
                objExcel.ActiveWorkbook.SaveAs strExcelPath
                If (Err.Number <> 0) Then
                    On Error GoTo 0
                    Wscript.Echo "Spreadsheet could not be saved as " _
                        & strExcelPath
                    Wscript.Echo "The path may be invalid."
                    strExcelPath = ""
                End If
                On Error GoTo 0
                objExcel.ActiveWorkbook.Close

                ' Quit Excel.
                objExcel.Application.Quit

                ' Clean up.
                adoRecordset.Close
                adoConnection.Close
                If (objFSO.FileExists(strTempfile) = True) Then
                    objFSO.DeleteFile(strTempFile)
                End If

                Wscript.Echo "Program Aborted"
                Wscript.Echo "Computers documented: " & (intCol - 1)
                If (strExcelPath <> "") Then
                    Wscript.Echo "See spreadsheet " & strExcelPath
                End If
                Wscript.Quit
            End If

            On Error Resume Next
            Set colSettings = objRemote.ExecQuery _
                ("SELECT * FROM Win32_QuickFixEngineering")
            If (Err.Number <> 0) Then
                On Error GoTo 0
                objSheet.Cells(8, intCol).Value = "Failed"
            Else
                On Error GoTo 0
                objSheet.Cells(8, intCol).Value = colSettings.Count
                strFixID = ""
                For Each objFix In colSettings
                    If (strFixID = "") Then
                        strFixID = objFix.HotFixID
                    Else
                        strFixID = strFixID & ";" & objFix.HotFixID
                    End If
                Next
                objSheet.Cells(9, intCol).Value = strFixID
                Set objFix = Nothing
            End If
            On Error Resume Next
            Set colSettings = objRemote.ExecQuery _
                ("SELECT * FROM Win32_ComputerSystem")
            If (Err.Number <> 0) Then
                On Error GoTo 0
                objSheet.Cells(10, intCol).Value = "Failed"
            Else
                On Error GoTo 0
                objSheet.Cells(10, intCol).Value = colSettings.Count
                For Each objComputer In colSettings
                    Select Case objComputer.DomainRole
                        Case 0
                            strRole = "Standalone Workstation"
                        Case 1
                            strRole = "Member Workstation"
                        Case 2
                            strRole = "Standalone Server"
                        Case 3
                            strRole = "Member Server"
                        Case 4
                            strRole = "Backup Domain Controller"
                        Case 5
                            strRole = "Primary Domain Controller"
                        Case Else
                            strRole = "Unknown"
                    End Select
                    objSheet.Cells(11, intCol).Value = strRole
                Next
                Set objComputer = Nothing
            End If
            Set colSettings = Nothing
            strStatus = " documented"
        End If
    Else
        objSheet.Cells(3, intCol).Value = "Computer Not Found"
        strStatus = " not on line"
    End If
    objExcel.Columns(intCol).ColumnWidth = 18

    intCol = intCol + 1
    adoRecordset.MoveNext
Loop
adoRecordset.Close

' Save spreadsheet and close the workbook.
On Error Resume Next
objExcel.ActiveWorkbook.SaveAs strExcelPath
If (Err.Number <> 0) Then
    On Error GoTo 0
    Wscript.Echo "Spreadsheet could not be saved as " & strExcelPath
    Wscript.Echo "The path may be invalid."
    strExcelPath = ""
End If
On Error GoTo 0
objExcel.ActiveWorkbook.Close

' Quit Excel.
objExcel.Application.Quit

' Clean up.
adoConnection.Close
If (objFSO.FileExists(strTempfile) = True) Then
    objFSO.DeleteFile(strTempFile)
End If

' Close display box.
MsgIE "IE_Quit"

Wscript.Echo "Done"
Wscript.Echo "Documented " & (intCol - 2) & " computers"
If (strExcelPath <> "") Then
    Wscript.Echo "See spreadsheet " & strExcelPath
End If

Function IsConnectible(ByVal strHost, ByVal intPings, ByVal intTO)
    ' Returns True if strHost can be pinged.
    ' Based on a program by Alex Angelopoulos and Torgeir Bakken.
    ' Modified 09/14/2010 to search for "Reply from" instead of "TTL=".
    Dim objFile, strResults

    If (intPings = "") Then
        intPings = 2
    End If
    If (intTO = "") Then
        intTO = 750
    End If

    Const OpenAsDefault = -2
    Const FailIfNotExist = 0
    Const ForReading = 1

    objShell.Run "%comspec% /c ping -n " & intPings & " -w " & intTO _
        & " " & strHost & ">" & strTempFile, 0, True

    Set objFile = objFSO.OpenTextFile(strTempFile, ForReading, _
        FailIfNotExist, OpenAsDefault)
    strResults = objFile.ReadAll
    objFile.Close

    Select Case InStr(strResults, "Reply from")
        Case 0
            IsConnectible = False
        Case Else
            IsConnectible = True
    End Select
End Function

Sub MsgIE(ByVal strMsg)
    ' Subroutine to display message in IE box and detect when the
    ' box is closed by the program or the user.
    On Error Resume Next
    If (strMsg = "IE_Quit") Then
        blnFlag = False
        objIE.Quit
    Else
        objIE.Document.Body.InnerText = strMsg
        If (Err.Number <> 0) Then
            Err.Clear
            blnFlag = False
            Exit Sub
        End If
        objShell.AppActivate strIETitle
    End If
End Sub

Sub InitIE(ByVal strMsg)
    ' Subroutine to initialize the IE display box.
    Dim intWidth, intHeight, intWidthW, intHeightW
    Set objIE = CreateObject("InternetExplorer.Application")
    objIE.ToolBar = False
    objIE.StatusBar = False
    objIE.Resizable = False
    objIE.Navigate("about:blank")
    Do Until objIE.readyState = 4
        Wscript.Sleep 100
    Loop
    intWidth = objIE.document.ParentWindow.Screen.AvailWidth
    intHeight = objIE.document.ParentWindow.Screen.AvailHeight
    intWidthW = objIE.document.ParentWindow.Screen.AvailWidth * .60
    intHeightW = objIE.document.ParentWindow.Screen.AvailHeight * .35
    objIE.document.ParentWindow.resizeto intWidthW, intHeightW
    objIE.document.ParentWindow.moveto (intWidth - intWidthW)/2, (intHeight - intHeightW)/2
    objIE.document.Write "<body> " & strMsg & " </body></html>"
    objIE.document.ParentWindow.document.body.style.backgroundcolor = "LightBlue"
    objIE.document.ParentWindow.document.body.scroll="no"
    objIE.document.ParentWindow.document.body.style.Font = "10pt 'Courier New'"
    objIE.document.ParentWindow.document.body.style.borderStyle = "outset"
    objIE.document.ParentWindow.document.body.style.borderWidth = "4px"
    objIE.document.Title = strIETitle
    objIE.Visible = True
    Wscript.Sleep 100
    objShell.AppActivate strIETitle
End Sub

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jmohan0302Author Commented:
Thanks Fouad. Howeve, I am looking for the desired output and serverlist should be for a list of servers and not for all the servers in domain. Thanks
Will SzymkowskiSenior Solution ArchitectCommented:
The below script should get everything you have requested.

$Log = "c:\filename.csv"
$Computers = Get-Content "c:\filename.txt"

ForEach ($Comp in $Computers) 
    {

$ComputerSystem = Get-WmiObject -Class win32_computersystem -ComputerName $Comp
$ComputerOS = Get-WmiObject -Class win32_operatingsystem -ComputerName $Comp
$ComputerCPU = Get-WmiObject -Class win32_processor -ComputerName $Comp
$ComputerMem = Get-WmiObject -Class win32_physicalmemory -ComputerName $Comp
$ComputerIP = Get-WmiObject -Class win32_networkadapterconfiguration -ComputerName $Comp | select -ExpandProperty IPAddress
$ComputerGW = Get-WmiObject -Class win32_networkadapterconfiguration -ComputerName $Comp | select -ExpandProperty DefaultIPGateway
$ComputerDisk = Get-WmiObject -Class win32_logicaldisk -ComputerName $Comp | ? {$_.DriveType -eq "3"}
$ComputerCluster = Get-WmiObject -Class mscluster_resource -Namespace root\mscluster -ErrorAction SilentlyContinue -ComputerName $Comp

    $Data = [ordered]@{
              'ServerName'=$ComputerSystem.Name;
              'Manufacturer'=$ComputerSystem.Manufacturer;
              'Model'=$ComputerSystem.Model;
              'OS Name'=$ComputerOS.Caption;
              'Service Pack'=$ComputerOS.CSDVersion;
              'Total CPUs'=$ComputerCPU.CpuStatus;
              'Total Cores'=$ComputerCPU.NumberOfCores;
              'Memory'=$ComputerMem.TotalWidth[0];
              'IPAddress'=$ComputerIP[0,1,2,3,4];
              'Default Gateway'=$ComputerGW;
              'Drive Letter'=$ComputerDisk.DeviceID[0,1,2,3];
              'Free Space(GB)'=$ComputerDisk | ForEach-Object {[math]::Truncate($_.freespace / 1GB)};
              'Total Size (GB)'=$ComputerDisk | ForEach-Object {[math]::Truncate($_.Size / 1GB)};
              'Cluster Name'=$ComputerCluster.Name;
            }

        $DataOut = New-Object -TypeName PSObject -Property $Data

        $DataOut | Out-File $Log -append


}

Open in new window


Will.
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

jmohan0302Author Commented:
Will,

thanks. I am getting following error, when executing, thanks

elect-Object : Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value.
At E:\Info\Inv.ps1:11 char:98
+ $ComputerIP = Get-WmiObject -Class win32_networkadapterconfiguration -ComputerName $Comp | select <<<<  -ExpandProperty IPAddress
    + CategoryInfo          : InvalidArgument: (:) [Select-Object], PSArgumentNullException
    + FullyQualifiedErrorId : ArgumentNull,Microsoft.PowerShell.Commands.SelectObjectCommand
 
Select-Object : Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value.
At E:\Info\Inv.ps1:12 char:98
+ $ComputerGW = Get-WmiObject -Class win32_networkadapterconfiguration -ComputerName $Comp | select <<<<  -ExpandProperty DefaultIPGateway
    + CategoryInfo          : InvalidArgument: (:) [Select-Object], PSArgumentNullException
    + FullyQualifiedErrorId : ArgumentNull,Microsoft.PowerShell.Commands.SelectObjectCommand
 
Unable to index into an object of type System.UInt16.
At E:\Info\Inv.ps1:24 char:48
+               'Memory'=$ComputerMem.TotalWidth[ <<<< 0];
    + CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : CannotIndex
 
New-Object : Cannot validate argument on parameter 'Property'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At E:\Info\Inv.ps1:33 char:59
+         $DataOut = New-Object -TypeName PSObject -Property <<<<  $Data
    + CategoryInfo          : InvalidData: (:) [New-Object], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.NewObjectComman
jmohan0302Author Commented:
Any Update????
Will SzymkowskiSenior Solution ArchitectCommented:
Does this provide any results? Works completely fine in my lab. What are you putting in your txt file? Have you tried to just add one computer to the txt file and see if that works? Also make sure that the machines is online and pingable.

Will.
Senior IT System EngineerIT ProfessionalCommented:
Yes it works correctly Will.
Thanks.
jmohan0302Author Commented:
will check and let you know
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.