http://www.perlmonks.org?node_id=347786
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;
}