Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Hardware/Software Inventory

by shonorio (Hermit)
on Apr 24, 2004 at 00:26 UTC ( [id://347786]=sourcecode: print w/replies, xml ) Need Help??
Category: NT Admin
Author/Contact Info Solli Moreira Honorio shonorio@ig.com.br
Description: Script that show how can you use the WMI do inventory of hardware/software from a specific machine.
# Write by Solli Moreira Honorio - Brazil
# shonorio@ig.com.br
# You can use as a GPL license
use strict;
use Win32::OLE;
use Win32::OLE::Enum;
use Win32::TieRegistry(Delimiter=>"/");

my $Machine = '.'; #Dot (.) equals local computer in WMI
my ( %Hardware, %Software );


GetHardwareInfo ($Machine,\%Hardware);
GetSoftwareInfo ($Machine,\%Software);

print "Hardware Info\n";
foreach my $Key01 ( keys %Hardware )
{
  print "\t$Key01\n";
  foreach my $Arr (@{$Hardware{$Key01}})
  {
    foreach my $Key02 (keys %{$Arr})
    {
      print "\t\t$Key02 : $Arr->{$Key02}\n";
    }
  }
}

print "Software Info\n";
foreach my $Key01 ( keys %Software )
{
  print "\t$Key01\n";
  foreach my $Arr (@{$Software{$Key01}})
  {
    foreach my $Key02 (keys %{$Arr})
    {
      print "\t\t$Key02 : $Arr->{$Key02}\n";
    }
  }
}

######################################################################
+##########
# Method     GetHardwareInfo
# Get        Server name and hash ref to rerturn
# Return     hash ref
######################################################################
+##########
sub GetHardwareInfo
{
    my ( $Server, $HardwareInfo ) = @_;
    my ( $Rtrn, %MetaData, $WMIServices, @Var );

    @{$MetaData{Win32_BIOS}{Properties}}                  = qw (Manufa
+cturer Name PrimaryBIOS SerialNumber SMBIOSBIOSVersion SMBIOSMajorVer
+sion SMBIOSMinorVersion SMBIOSPresent Status Version);
    @{$MetaData{Win32_ComputerSystem}{Properties}}        = qw (Descri
+ption Manufacturer Model NumberOfProcessors ThermalState TotalPhysica
+lMemory);
    @{$MetaData{Win32_ComputerSystemProduct}{Properties}} = qw (Descri
+ption IdentifyingNumber Name SKUNumber UUID Vendor Version);
    @{$MetaData{Win32_DiskDrive}{Properties}}             = qw (BytesP
+erSector Description ErrorDescription ErrorMethodology Index Interfac
+eType Manufacturer MediaType Model Name Partitions PNPDeviceID SCSIBu
+s SCSILogicalUnit SCSIPort SCSITargetId SectorsPerTrack Signature Siz
+e Status StatusInfo TotalCylinders TotalHeads TotalSectors TotalTrack
+s TracksPerCylinder);
    @{$MetaData{Win32_IDEController}{Properties}}         = qw (Config
+ManagerErrorCode Manufacturer Name Status StatusInfo);
    @{$MetaData{Win32_LogicalDisk}{Properties}}           = qw (Name D
+riveType FileSystem Size SupportsFileBasedCompression VolumeName Volu
+meSerialNumber);
    @{$MetaData{Win32_PageFile}{Properties}}              = qw (Compre
+ssed CreationDate InitialSize MaximumSize Name);
    @{$MetaData{Win32_PhysicalMemory}{Properties}}        = qw (BankLa
+bel Capacity DeviceLocator MemoryType Speed);
    @{$MetaData{Win32_Processor}{Properties}}             = qw (CpuSta
+tus CurrentClockSpeed DeviceID Description ExtClock SocketDesignation
+ Role Name MaxClockSpeed Manufacturer LastErrorCode L2CacheSize);
    @{$MetaData{Win32_SCSIController}{Properties}}        = qw (Config
+ManagerErrorCode DriverName DeviceID Manufacturer Name Status StatusI
+nfo);
    @{$MetaData{Win32_NetworkAdapter }{Properties}}       = qw (Adapte
+rType ConfigManagerErrorCode Description DeviceID Index  LastErrorCod
+e MACAddress Manufacturer Name ProductName ServiceName TimeOfLastRese
+t);

    if ( $WMIServices = Win32::OLE->GetObject( "winmgmts:{impersonatio
+nLevel=impersonate,(security)}!//$Server/" ) )
    {
        foreach my $Instance ( keys %MetaData )
        {
            undef ( @Var );
            foreach my $Properties ( Win32::OLE::in( $WMIServices->Ins
+tancesOf( $Instance ) ) )
            {
                ++$#Var;
                foreach my $Property ( @{$MetaData{$Instance}{Properti
+es}} )
                {
                    $Var[$#Var]{$Property} = $Properties->{$Property};
                }
            }
            push ( @{$HardwareInfo->{$Instance}}, @Var );
        }
    }
    else
    {
        return Win32::OLE->LastError();
    }
}

######################################################################
+##########
# Method     GetSoftwareInfo
# Get        Server name and hash ref to rerturn
# Return     hash ref
######################################################################
+##########
sub GetSoftwareInfo
{
    my ( $Server, $SoftwareInfo ) = @_;
    my ( $Rtrn, %MetaData, $WMIServices, @Var, %Uninstall );

    @{$MetaData{Win32_OperatingSystem}{Properties}} = qw (BootDevice B
+uildNumber BuildType Caption CodeSet CountryCode CSDVersion CSName Cu
+rrentTimeZone ForegroundApplicationBoost InstallDate LargeSystemCache
+ LastBootUpTime Locale Manufacturer Organization OSLanguage OSProduct
+Suite Primary ProductType RegisteredUser SerialNumber ServicePackMajo
+rVersion ServicePackMinorVersion Version WindowsDirectory);
    @{$MetaData{Win32_NTEventlogFile}{Properties}}  = qw (Compressed C
+reationDate FileSize LogfileName MaxFileSize Name NumberOfRecords Ove
+rwriteOutDated OverWritePolicy Status);

    if ( $WMIServices = Win32::OLE->GetObject( "winmgmts:{impersonatio
+nLevel=impersonate,(security)}!//$Server/" ) )
    {
        foreach my $Instance ( keys %MetaData )
        {
            undef ( @Var );
            foreach my $Properties ( Win32::OLE::in( $WMIServices->Ins
+tancesOf( $Instance ) ) )
            {
                ++$#Var;
                foreach my $Property ( @{$MetaData{$Instance}{Properti
+es}} )
                {
                    $Var[$#Var]{$Property} = $Properties->{$Property};
                }
            }
            push ( @{$SoftwareInfo->{$Instance}}, @Var );
        }

        # Get the Installed software
        %Uninstall = %{ $Registry->{"//$Server/HKEY_LOCAL_MACHINE/SOFT
+WARE/Microsoft/Windows/CurrentVersion/Uninstall"} };
        undef ( @Var );

        foreach my $Key ( keys %Uninstall )
        {
            next if ( $Key =~ m/^\//i );
            next if ( $Uninstall{$Key}->{'/DisplayName'} eq '' );
            $Var[++$#Var]{Version}   = $Uninstall{$Key}->{'/DisplayVer
+sion'};
            $Var[$#Var]{DisplayName} = $Uninstall{$Key}->{'/DisplayNam
+e'};
            $Var[$#Var]{InstallDate} = $Uninstall{$Key}->{'/InstallDat
+e'};
            $Var[$#Var]{Publisher}   = $Uninstall{$Key}->{'/Publisher'
+};
            $Key                     =~ s/\///ig;
            $Var[$#Var]{ProdID}      = $Key;
        }
        push ( @{$SoftwareInfo->{SoftwareInstalled}}, @Var );

        # Get the hotfix
        %Uninstall = %{ $Registry->{"//$Server/HKEY_LOCAL_MACHINE/SOFT
+WARE/Microsoft/Windows NT/CurrentVersion/Hotfix"} };
        undef ( @Var );

        foreach my $Key ( keys %Uninstall )
        {
            $Var[++$#Var]{Version}   = $Uninstall{$Key}->{'/Comments'}
+;
            $Key                     =~ s/\///ig;
            $Var[$#Var]{ProdID}      = $Key;
        }
        push ( @{$SoftwareInfo->{HotFix}}, @Var );

        return undef;
    }
    else
    {
        return Win32::OLE->LastError();
    }
    return undef;
}
Replies are listed 'Best First'.
Re: Hardware/Software Inventory
by Anonymous Monk on Feb 14, 2005 at 15:55 UTC
    Hi, I was just wondering how you can make this target a machine on a network. I have tried changing the '.' in line 9 to the computer name of a machine on my network and it doesnt seem to work.
    Is this suppose to work for computers on a network or just locally? Or is the permissions on the target pc preventing access?
    If it is the permissions, is it possible and how could I modify this script to allow for username & password to be entered?

    Many thanks, Jace

      Jace,

      To access remote computer just change the '.' in line 9 to computer name without slashs ('\'), like my $Machine = "wks", I've test with success on my enviroment. But remeber that WMI must be installed on remote machine. WMI is installed by default just for Win2K or later.

      Solli Moreira Honorio
      Sao Paulo - Brazil
        Hm this doesn't work for me, am I doing something wrong? I thought it would be great as one of my co-workers needs to inventory software company wide for license compliance I am getting a syntax error in line 48 near sub GetHardwareInfo" followed by a cannot use global @_ in "my" at c:\perl\bin\mytest.pl line 49 near =@" sytax error at c:\perl\bin\mytest.pl line 109 near } execution of c:\perl\bin\mytest.pl aborted due to compiliation errors.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://347786]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-03-19 04:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found