|
|
|||||||
Hello all, I am rather new to this and was hoping someone could lend a hand on how to go about a task I have. I need to query all the disk space available on multiple servers across our network. After logging into the first 15 machines to check the details, I remembered how I used KiXtart a while back to assist me with multiple printer creations and wondered if I could get lucking again. My problem is that I am not much of a scriptor. I have about 60 machines I need to know what their current Free space and capacity is and was wondering if anyone could point me in a direction to automate this process? Thank you so much. Richard |
||||||||
|
|
|||||||
The WMISysInfo() UDF will query lots of information from local or remote systems. You can call that from a loop that enumerates a list of computers. The array that is returned contains 3 strings of interest - list of drive letters, list of drive capacities, and list of free space on the drives. You would use Split() to break those values into arrays where you could generate your report quite easily. I think I posted a copy here, but you can get the latest copy from the Resources section of my web site (in my signature). There's also a HWInfo() UDF that only gathers the hardware settings, but it isn't as efficient as the WMISysInfo() UDF. Glenn |
||||||||
|
|
|||||||
Glenn, thank you so much. I will check this out. I really appreciate your assistance. |
||||||||
|
|
|||||||
Wow...I may be in over my head here. I just tried to sort some of this out and my eyes went crossed. My apologies, I am usually the Citrix Administrator. But have some downtime to lend a hand. |
||||||||
|
|
|||||||
It's not as scary as it looks... Consider the UDF as a "black box" like any other function - you ask a question and get an answer. Try this: Download the UDF & save it as "WMISysInfo.UDF" in the root of C: (for now). If you have a preferred place for your UDFs, put it there and modify the path in the CALL statement. Next, try the following example: Code: Break On ; Load the UDF Call "C:\temp\WMISysInfo.UDF" ; or specify your alternate location ; print the header 'Drv Capacity Free <!>' ? ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) $Computer = 'lghbsappp04' ; load the array from the computer $aSysInfo = WMISysInfo($Computer) ; Examine the disk drives & capacities $D_Letters = Split($aSysInfo[32], ',') $D_Capacities = Split($aSysInfo[33], ',') $D_FreeSpace = Split($aSysInfo[34], ',') For $Index = 0 to UBound($D_Letters) Left($D_Letters[$Index] + ' ', 4) ; 150 spaces between quotes Right(' ' + $D_Capacities[$Index], 15) Right(' ' + $D_FreeSpace[$Index], 15) If Val($D_FreeSpace[$Index]) < 500 ' <Low!>' EndIf ? Next This should display a simple report for all drives on that system. If you wrap this logic into a loop, enumerating a list of computers, you can get a report for each computer. Glenn |
||||||||
|
|
|||||||
Well here is something to get you started. It's old code and could use some updating but should work. Then you might want to read a file of server names to feed it in a loop. You could also use WMI to find the drives to feed it as well. Code: If Not @LogonMode Break On EndIf Dim $SO $SO=SetOption('Explicit','On') $SO=SetOption('NoVarsInStrings','On') $SO=SetOption('NoMacrosInStrings','On') $SO=SetOption('WrapAtEOL','On') Dim $Dsize $Dsize = GetDiskFreeSpace('your SERVER name here','D') 'Bytes Total Disk Size is: ' + $Dsize[0] ? 'Percent Used is: ' + $Dsize[1] + '%' ? 'Percent Unused is: ' + $Dsize[2] +'%' ? 'Bytes Left Unused is: ' + $Dsize[3] ? Function GetDiskFreeSpace($sComputer,$Drive) Dim $objWMIService, $colDisks, $objDisk Dim $FreeSpace, $TotalSize, $pctFreeSpace, $pctUsed $objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" + $sComputer + "\root\cimv2") If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf $colDisks = $objWMIService.ExecQuery('Select * from Win32_LogicalDisk Where DeviceID = '+"'"+$Drive+":'") If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf For Each $objDisk in $colDisks If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf $FreeSpace = CDBL($objDisk.FreeSpace) $TotalSize = CDBL($objDisk.Size) $pctFreeSpace = FormatNumber(($FreeSpace / $TotalSize * 100),2) $FreeSpace = FormatNumber($FreeSpace,-1,,-2) $pctUsed = CDBL(100) - $pctFreeSpace $pctUsed = FormatNumber($pctUsed,-1,,-2) $TotalSize = FormatNumber($TotalSize,-1,,-2) Next ;Bytes Total Disk Size = $TotalSize ;Percent Used = $pctUsed ;Percent Unused = $pctFreeSpace ;Bytes Left Unused = $FreeSpace $GetDiskFreeSpace = $TotalSize, $pctUsed, $pctFreeSpace, $FreeSpace Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndFunction Here is a script that will read a file from the same directory the script is ran from and then will attempt to locate the shares like C$ D$ E$ etc.. ignoring the IPC$ and ADMIN$ shares. It too could use some updating to the code as it is quite old and was designed for some other stuff as well at the time. Code: Break On Dim $SO,$Server,$Servers,$ValidSystem,$Share,$Item,$HS,$x,$File,$Report,$sComputer,$Send,$Results,$Results1,$Results2 Dim $Results3,$NB,$Arp,$Status $SO=SetOption('Explicit','On') $SO=SetOption('NoVarsInStrings','On') $Servers=ReadFile(@ScriptDir+'\servers.txt') $File = @ScriptDir+'\ServerDiskSpace.txt' If Exist($File) Del $File EndIf $Report = RedirectOutput($File,1) For Each $sComputer In $Servers If $sComputer $Send=0 $Results=Join(wshpipe('ping '+$sComputer+' -n 1',1),@CRLF) If UBound(Split($sComputer,'.'))=3 ;IP was supplied from list $NB='IP' $Arp=0 $Results1=Trim(Split(Split(Split($Results,":")[4],"Received = ")[1],", Lost")[0]) Else ; NetBIOS name was supplied from list $NB='NetBIOS' $Arp=1 $Results1=Trim(Split(Split(Split($Results,":")[4],"Received = ")[1],", Lost")[0]) $Results2=Trim(Split(Split($Results,"[")[1],"]")[0]) $Results3=Trim(Split(Split($Results,"could")[1],"find")[0]) EndIf If $Arp ; NetBIOS name was supplied from list Select Case $Results3 $Status=$sComputer+' using '+$NB+' is not in WINS-DNS' ? $Status $Send=0 Case $Results2 If $Results1 >0 $Status=$sComputer+' using '+$NB+' '+$Results2+' is responding to ping' $Send=1 Else $Status=$sComputer+' using '+$NB+' has WINS-DNS entry but is not responding.' ? $Status $Send=0 EndIf Case 1 $Status=$sComputer+' generated an unknown error '+ 'ERR: '+@ERROR ? $Status $Send=0 EndSelect Else ;IP was supplied from list If $Results1 >0 $Status=$sComputer+' using '+$NB+' is responding to ping' $Send=1 Else $Status=$sComputer+' using '+$NB+' is NOT responding to ping' ? $Status $Send=0 EndIf EndIf If $Send If ConfirmWMI($sComputer) $HS=ListHiddenShares($sComputer) $HS=QS(Split(Join(Split($HS,CHR(42)),CHR(32)),CHR(47))) ;Sort the list using QS UDF For $x=0 To UBound($HS) If $x ? $sComputer + CHR(32) + $HS[$x] EndIf Next EndIf EndIf EndIf Next $Report = RedirectOutput("") Function WshPipe($ShellCMD, OPTIONAL $NoEcho) Dim $oExec, $Output $oExec = CreateObject("WScript.Shell").Exec($ShellCMD) If Not VarType($oExec)=9 $WshPipe="WScript.Shell Exec Unsupported" Exit 10 EndIf $Output = $oExec.StdOut.ReadAll + $oExec.StdErr.ReadAll If Not $NoEcho $Output Endif $WshPipe=Split(Join(Split($Output,CHR(13)),CHR(32)),CHR(10)) Exit($oExec.ExitCode) EndFunction Function ListHiddenShares($sComputer) Dim $objWMIService,$colShares,$objShare,$HiddenShare If Not $sComputer $sComputer = @WKSTA EndIf $sComputer = '\\' + $sComputer + '\' $objWMIService = GetObject("winmgmts:" + "{impersonationLevel=impersonate}!" + $sComputer + "root\cimv2") $colShares = $objWMIService.ExecQuery("Select * from Win32_Share") For each $objShare In $colShares If $objShare.Type = '-2147483648' And Not InStr($objShare.Name,'ADMIN$') $HiddenShare = $HiddenShare + $objShare.Name + CHR(42) + Diskspace($sComputer+ $objShare.Name) + CHR(47) EndIf Next $ListHiddenShares = $HiddenShare EndFunction Function Diskspace(optional $drive, optional $format) Dim $objWMIService, $sWQL, $colDrives, $objDrive If Not $drive $drive='%WINDIR%' EndIf $format=Val($format) If $format<5 $format=IIf($format=1,1024,IIf($format=2,1024.0*1024,IIf($format=3,1024.0*1024*1024,IIf($format=4,1024.0*1024*1024*1024,1)))) $diskspace=CDBL(GetDiskSpace($drive))/$format Else $objWMIService=GetObject('winmgmts:{impersonationLevel=impersonate}!\\'+@WKSTA+'\root\cimv2') $sWQL = "SELECT Size, FreeSpace FROM Win32_LogicalDisk WHERE Name='"+Left($drive,2)+"'" $colDrives=$objWMIService.ExecQuery($sWQL) For Each $objDrive in $colDrives $diskspace=CDBL($objDrive.FreeSpace)/CDBL($objDrive.Size)*100 Next EndIf Exit @ERROR EndFunction Function ConfirmWMI(Optional $sComputer) Dim $Computer,$Namespace,$WinDir,$Target,$WMIVer,$objWMIService,$WinDrive If Not $sComputer $sComputer = @WKSTA EndIf $sComputer = '\\' + $sComputer + '\' $WinDir = $sComputer+Join(Split(ReadValue($sComputer+ 'HKLM\Software\Microsoft\Windows NT\CurrentVersion', 'SystemRoot'),':'),Chr(36)) If @ERROR Exit @ERROR EndIf $Target = $WinDir + '\system32\wbem\wbemdisp.dll' If Exist($Target) $WMIVer = Trim(GetFileVersion($Target,'BinFileVersion')) If @ERROR Exit @ERROR EndIf Else Exit 2 EndIf $ConfirmWMI=$WMIVer $Namespace = "root\cimv2" If $WMIVer $objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!" + $sComputer + $Namespace) If @ERROR Exit Val("&"+Right(DecToHex(@ERROR),4)) Else Exit 0 EndIf EndIf Exit 2 EndFunction Function ReadFile($file) Dim $lf, $f, $_, $t $lf=Chr(10) $f=FreeFileHandle $_=Open($f,$file) If @ERROR Exit @ERROR EndIf Do $t=$t+$lf+ReadLine($f) Until @ERROR $_=Close($f) $ReadFile=Split(SubStr($t,2),$lf) EndFunction Function QS($a) DIM $b[32],$c[32],$d,$e,$f,$g,$h,$i,$j,$k,$l $b[0]=0 $c[0]=Ubound($a) $d=0 While $d >=0 $e=$b[$d] $f=$c[$d] While $e < $f $h=$e+($f-$e)/2 $k=$a[$e] $A[$e]=$A[$h] $A[$h]=$k $i=$e+1 $j=$f $l=0 Do While ($i<$j) And $A[$e] > $A[$i] $i=$i+1 Loop While ($j>=$i) And $A[$j] > $A[$e] $j=$j-1 Loop IF $i>=$j $l=1 Else $k=$A[$i] $A[$i]=$A[$j] $A[$j]=$k $j=$j-1 $i=$i+1 EndIf Until $l=1 $k=$a[$e] $a[$e]=$a[$j] $a[$j]=$k $g=$j If $g-$e <= $f - $g If $g+1 < $f $b[$d]=$g+1 $c[$d]=$f $d=$d+1 EndIf $f=$g-1 Else If $g-1 > $e $b[$d]=$e $c[$d]=$g-1 $d=$d+1 EndIf $e=$g+1 EndIf Loop $d=$d-1 Loop $qs=$a EndFunction |
||||||||
|
|
|||||||
I may have to try this one from Glenn out later on |
||||||||
|
|
|||||||
Thanks again. I assume the kix32.exe is what "kicks" the UDF off? So I would run it from a command prompt calling up UDF? Thank you for tolerating my silly questions. |
||||||||
|
|
|||||||
With Doc's example of reading a file containing a list of computers, you can combine the two scripts and get a pretty detailed report. If the drive letter is "MV:", it indicates a "mounted volume", you could split array element 31 to get the mount points and add that to your report. Considering the single query to WMISysInfo returns almost 40 pieces of information, you could create a fairly sophisticated reporting system with minimal effort. Glenn |
||||||||
|
|
|||||||
My goodness.....I am entering a world here that both scares and entices at the same time. The possibilities seem endless. |
||||||||
|
|
|||||||
The "CALL" statement references the exact path/file where the UDF exists. If it was a script - it would be executed right then, but being a UDF, the CALL statement simply loads the external UDF into memory, allowing it to be invoked by later calls to the function within the main script. Try the first example - as is, except for changing the name of the computer you want to query. You should get a simple report on the screen that looks like this: Code: Drv Capacity Free <!> C: 12584644608 8453046272 <Low!> D: 35993792512 31628820480 E: 14558744576 14364459008 One change to the code I posted earlier - the VAL() should be a CDbl(), and the 500 should be a 500000 - I'm sure you'd want to be warned at 500 MEG and not 500 BYTES!! I forgot that the values were bytes. Glenn |
||||||||
|
|
|||||||
Glenn, I am getting: ERROR : FUNCTION without ENDFUNCTION! LINE : 174 I think I am making the mistake of treating this like a script. I used to have the kix32.exe call up a .kix file for my printers. That was the only other time I every used KiXtart. God, you guys must hate people like me! |
||||||||
|
|
|||||||
Where will this report turn up? I do not see anything being returned. Is there a location it is dropped in or will it just pop on the screen? |
||||||||
|
|
|||||||
OK - try this.. Here's the script AND the UDF, all in one file. 1. Copy the following script 2. Paste into Notepad 3. Edit the line between the ; ===== headers to define a computer on your network that you have access to 4. Save as "DskInfo.kix" 5. Run as KIX32.EXE DSKINFO.KIX You should get a report of each disk capacity. If you don't, check that the computer name is correct, and that you have access to the remote computer. You can verify by "DIR \\COMPUTER\C$" The difference between this and the earlier version is that the UDF is included directly in the file, and not loaded from an external file. I prefer this method, as it assures me the script will always work without reliance on external files. My KGen tool (Part of my KixDev product) assembles finished scripts in this manner, but automatically identifies which UDFs are required. I added a simple error check - if the call to the UDF doesn't return data, I display a message and exit. Note that this example is very basic in terms of coding - vars are not declared, and vars/macros are permitted in strings. My emphasis was on providing a usable code SAMPLE, which demonstrates the capability. It's up to you to A) apply good coding process to your finished script, and B) wrap this logic in a loop to process many computers instead of just one. That should provide you with a decent shove in the right direction, and enough stuff to do on your own to make it a worthwhile learning experience. Regards, Glenn Code: Break On ; print the header 'Drv Capacity Free <!>' ? ;===================================================== ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) $Computer = 'COMPUTER' ;===================================================== ; load the array from the computer $aSysInfo = WMISysInfo($Computer) If UBound($aSysInfo) = -1 'Bad computer name or no access!' ? Quit 1 EndIf ; Examine the disk drives & capacities $D_Letters = Split($aSysInfo[32], ',') $D_Capacities = Split($aSysInfo[33], ',') $D_FreeSpace = Split($aSysInfo[34], ',') For $Index = 0 to UBound($D_Letters) Left($D_Letters[$Index] + ' ', 4) ; 15 spaces between quotes Right(' ' + $D_Capacities[$Index], 15) Right(' ' + $D_FreeSpace[$Index], 15) If CDbl($D_FreeSpace[$Index]) < 500000 ' <Low!>' EndIf ? Next ; ========================================================== ; UDF Follows ; ========================================================== ;; ;;====================================================================== ;; ;;FUNCTION WMISysInfo() ;; ;;ACTION Returns an array containing system information ;; from local or remote system ;; ;;AUTHOR Glenn Barnas ;; ;;VERSION 1.0 / 2007/10/20 - First release ;; ;;SYNTAX WMISysInfo([host] [,AuthPtr]) ;; ;;PARAMETERS host - OPTIONAL - name of system to query ;; ;; AuthPtr - OPTIONAL - pre-authenticated WMI object pointer ;; Use WMIAuthentication() udf to create the AuthPtr value ;; AuthPtr is not needed if user has admin rights ;; ;;REMARKS Replaced independent OSInfo and HWInfo UDFs ;; ;;RETURNS 40 element array ;; 0 short/full operating system description ;; 1 kernel description (Win2K, WinXP, Win2K3, Vista) ;; 2 operating system role (workstation, member server, domain controller) ;; 3 operating system service pack level ;; 4 operating system build level ;; 5 uni/multi-processor type ;; 6 Computer Name ;; 7 registered owner,organization ;; 8 Serial Number ;; 9 Install Date - YYYY/MM/DD hh:mm:ss ;; 10 Local Date/Time - YYYY/MM/DD hh:mm:ss ;; 11 Last Boot Time - YYYY/MM/DD hh:mm:ss ;; 12 TimeZone info (Std, Daylight, Bias) ;; 13 Primary Domain Affiliation ;; 14 Installed Hotfix list ;; 15 OS Version (numeric) ;; 16 Future Use ;; 17 O/S Architecture ;; 18 Install Method (Clean, Upgrade, SysPrep) ;; 19 RAM/PageFile Info (location MinSize MaxSize) ;; 20 System Brand ;; 21 System Model ;; 22 System S/N ;; 23 System BIOS Revision ;; 24 Processor Type ;; 25 Processor Speed ;; 26 Processor Count (Physical) ;; 27 Processor Count (Logical) ;; 28 Processor Cores ;; 29 Physical Memory ;; 30 Fixed-Disk Labels, null if none ;; 31 Fixed-Disk Mount Point ("d:\" for drives, path for mounted volumes) (2K3 & higher) ;; 32 Fixed-Disk Drives (A:-Z:, or "MV:" for mounted Volumes) ;; 33 Fixed-Disk Capacities, bytes ;; 34 Fixed-Disk FreeSpace, bytes ;; 35 CD-ROM Disk List ;; 36 Connected Network Drives ;; 37 Hardware Architecture ;; 38 Future Use ;; 39 Future Use ;; ;;DEPENDENCIES WMI support ;; ;;TESTED WITH W2K, WXP, W2K3, Vista, X64 ;; ;;EXAMPLES $Host = '' ;; $aHWI = WMIHWInfo($Host) ;; $Host ' has ' $aHWI[6] ' Physical/Logical processors!' ;; ;; $Host = 'server' ;; $objWMI = WMIAuthenticate('computer', 'userid', 'User-P@ss!') ;; $Up = WMIUptime($Host, $objWMI) ;; 'Secure host ' $Host ' has been up for ' $Up[0] ' days!' ; Function WMISysInfo(OPTIONAL $_Target, OPTIONAL $_pAuth) Dim $objWMIService, $colItems, $objItem ; WMI object vars Dim $_SI[39] ; Var for return array Dim $_, $_Delim, $_SRoot, $_WFile, $_OSVer $_Target = IIf($_Target, $_Target, '.') If InStr($_Target, '\') $_Target = Join(Split($_Target, '\'), '') EndIf If $_pAuth $objWMIService = $_pAuth Else $objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Target + '\root\cimv2') If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf EndIf ; O/S SECTION ####################################################### ; OperatingSystem ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48) For Each $objItem in $colItems $_SRoot = '\\' + $_Target + '\' + Join(Split($objItem.SystemDirectory, ':'), Chr(36)) + '\' $_SI[0] = Trim(Split($objItem.Name, '|')[0]) $_SI[15] = $objItem.Version $_ = _osid($_SI[0], $_SI[15]) ; get kernel name, fix OS name $_SI[0] = $_[0] $_SI[1] = $_[1] $_OSVer = Trim(Join(Split($_SI[15], '.', 2), '.')) $_ = Split($objItem.CSDVersion, ' ') $_SI[3] = $_[UBound($_)] $_SI[4] = $objItem.BuildNumber $_SI[5] = $objItem.BuildType $_SI[6] = $objItem.CSName $_SI[7] = $objItem.RegisteredUser + '/' + $objItem.Organization $_SI[8] = $objItem.SerialNumber ; Translate the following in to standard date strings (yyyy/mm/dd hh:mm:ss) $_ = $objItem.InstallDate $_SI[9] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.LocalDateTime $_SI[10] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.LastBootUpTime $_SI[11] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.OSArchitecture $_SI[17] = IIf($_, $_, '32-bit') Next $colItems = 0 ; Time Zone ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_TimeZone",,48) For Each $objItem in $colItems $_SI[12] = $objItem.StandardName + ' / ' + $objItem.DaylightName + ' / ' + Abs($objItem.Bias) / 60 Next $colItems = 0 ; Domain ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_NTDomain",,48) For Each $objItem in $colItems $_SI[13] = $objItem.DNSForestName + ',' + $objItem.DomainName Next $colItems = 0 ; Hotfixes ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering",,48) For Each $objItem in $colItems If InStr('KQ', Left($objItem.HotFixID, 1)) $_SI[14] = $_SI[14] + ' ' + $objItem.HotFixID EndIf Next $_SI[14] = SubStr($_SI[14], 2) ; trim result $colItems = 0 ; PageFile ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_PageFile",,48) For Each $objItem in $colItems $_SI[19] = $_SI[19] + ' ' + $objItem.EightDotThreeFileName + ' ' + $objItem.InitialSize + ' ' + $objItem.MaximumSize Next $colItems = 0 ; Check for build status $_SI[18] = 'Clean' $_WFile = $_SRoot + Chr(36) + 'winnt' + Chr(36) + '.inf' If Exist($_WFile) If ReadProfileString($_WFile, 'Data', 'StandardServerUpgrade') = 'yes' Or ReadProfileString($_WFile, 'Data', 'WinNtUpgrade') = 'yes' $_SI[18] = 'Upgrade' EndIf If ReadProfileString($_WFile, 'Unattended', 'InstallFilesPath') $_SI[18] = 'SysPrep' EndIf EndIf ; HARDWARE SECTION ####################################################### ; ComputerSystem ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48) For Each $objItem in $colItems $_ = 'Standalone Workstation', 'Member Workstation', 'Standalone Server', 'Member Server', 'Backup Domain Controller', 'Primary Domain Controller' $_SI[2] = $_[Val($objItem.DomainRole)] $_SI[37] = Left($objItem.SystemType, 3) $_SI[20] = $objItem.Manufacturer $_SI[21] = $objItem.Model $_SI[26] = $objItem.NumberOfProcessors $_SI[29] = $objItem.TotalPhysicalMemory $_ = CInt((CDbl($_SI[29]) + 655360.0) / 1048576.0) $_SI[19] = '' + $_ + $_SI[19] Next $colItems = 0 ; BIOS ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_BIOS",,48) For Each $objItem in $colItems $_SI[22] = $objItem.SerialNumber $_Delim = '' For Each $_ in $objItem.BIOSVersion $_SI[23] = $_SI[23] + $_Delim + $_ $_Delim = ',' Next Next $colItems = 0 ; Processor ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_Processor",,48) For Each $objItem in $colItems $_SI[24] = Trim($objItem.Name) $_SI[25] = $objItem.MaxClockSpeed $_SI[27] = $objItem.NumberOfLogicalProcessors $_SI[28] = $objItem.NumberOfCores Next $colItems = 0 ; Disk Storage ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_LogicalDisk",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 ; fixed disk $_SI[30] = $_SI[30] + ',' + $objItem.VolumeName $_SI[31] = $_SI[31] + ',' + $objItem.Caption + '\' $_SI[32] = $_SI[32] + ',' + $objItem.Caption $_SI[33] = $_SI[33] + ',' + $objItem.Size $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf If $objItem.DriveType = 5 ; CD-ROM $_SI[35] = $_SI[35] + ',' + $objItem.Caption EndIf If $objItem.DriveType = 4 ; Network Drive $_SI[36] = $_SI[36] + ',' + $objItem.Caption + '=' + $objItem.ProviderName EndIf Next $colItems = 0 If $_OSVer > 5.1 ; only supported on W2K3 and higher - return mounted volume info $colItems = $objWMIService.ExecQuery("Select * from Win32_Volume",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 And $objItem.DriveLetter = '' $_SI[30] = $_SI[30] + ',' + $objItem.Label $_SI[31] = $_SI[31] + ',' + $objItem.Caption $_SI[32] = $_SI[32] + ',' + 'MV:' $_SI[33] = $_SI[33] + ',' + $objItem.Capacity $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf Next EndIf $colItems = 0 ; trim leading "," from strings For $_ = 30 to 36 $_SI[$_] = SubStr($_SI[$_], 2) Next ; Return the array $WMISysInfo= $_SI Exit 0 EndFunction ; _osid - supporting function ; Identifies the release version (beta, RTM, Preview, etc), defines a "kernel short name", ; and removes special characters from the description string Function _osid($_Vs, $_Vn) Dim $_ Dim $_Srel ; string of release IDs Dim $_Vmaj ; Major version number Dim $_Vmin ; Minor version number Dim $_Vrel ; Release number Dim $_aR[1] ; Short (KernelID) name, Descriptive Name $_ = Split($_Vn + '.0.0', '.', 3) $_Vmaj = Val($_[0]) $_Vmin = Val($_[1]) $_Vrel = $_[2] ; clean up the O/S description string - remove special chars $_Vs = Join(Split($_Vs, Chr(153)), '') ; (tm) $_Vs = Join(Split($_Vs, Chr(169)), '') ; (c) $_Vs = Join(Split($_Vs, Chr(174)), '') ; (r) Select Case $_Vmaj = 5 And $_Vmin = 0 ; Win2K $_aR[1] = 'Win2K' $_Srel = '1515=(Beta 2),2031=(Beta 3),2183=(Beta 3),2128=(Beta 3 RC2),2195=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 5 And $_Vmin = 1 ; WinXP $_aR[1] = 'WinXP' $_Srel = '2505=(RC1),2600=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 5 And $_Vmin = 2 ; Win2K3 $_aR[1] = 'Win2K3' $_Srel = '3718=(Eval),3790=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 6 And $_Vmin = 0 ; Vista $_aR[1] = 'Vista' $_Srel = '6000=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case 1 $_aR[1] = 'Unknown' EndSelect $_aR[0] = $_Vs $_osid = $_aR EndFunction |
||||||||
|
|
|||||||
The very fist script I posted should work as is. Just provide it a server name. Perhaps not as fancy as Glenns The second example includes all UDF code as well. Just create a list of servers you want to check in a file called servers.txt. It writes it all out to a ServerDiskSpace.txt file in the same folder the script is ran from. From a DOS Console with KIX32.EXE in the folder or path. KIX32.EXE DISKSPACE.KIX Then open ServerDiskSpace.txt with notepad. |
||||||||
|
|
|||||||
Glenn thanks again. I don't think I am dropping the computer name in the proper place or maybe not using the proper syntax. EUREKA..I got it. But I have to get it to MB's at least. |
||||||||
|
|
|||||||
Thanks, Doc. I am trying them both. I need to establish some comfort level here. |
||||||||
|
|
|||||||
No problem. Either one should work for you. Glenn has some nice code and documents it better than most of us |
||||||||
|
|
|||||||
Change the RED part to a valid computer name on your network! ;===================================================== ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) $Computer = ' COMPUTER' ;===================================================== Once it works, and you configure the results the way you like, you can put the code below the $Computer= line, and up to the beginning of the UDF definition into a loop to process multiple computers. Obviously, delete or comment out the $Computer= part when you get to this point. Try something like this to read a list of computer names from NAMES.TXT: Code: If Open(3, "NAMES.TXT") = 1 $Computer = ReadLine(3) While Not @ERROR ; reporting code goes here... $Computer = ReadLine(3) Loop $ = Close(3) EndIf Again, this is example code, not polished, prim, and proper. This example writes the data to the screen, but you can simply add a RedirectOutput('DiskReport.txt') to the beginning of the script. Don't forget to close the redirect with RedirectOutput(''), and capture the return values with $RC = in front of each RedirectOutput call. You'll probably want to delete or rename the output file first, since it will simply append the output to any existing file. You need MBytes - the disk values are in bytes, and are STRINGS!! You need to divide by 1024 to get KBytes, or 1048576.0 to get MBytes. You're dealing with large values - above 32768, so should convert to doubles first - like this: Right(' ' + CDbl($D_Capacities[$Index]) / 1048576.0, 15) This converts the value to a double, divides it by 1 meg (as a double), converts the whole mess back to a string by prepending it with spaces, then trims the rightmost 15 characters. Phew! Might be easier to do this one step at a time till you get the hang of it. Glenn PS Post your code if you get in a jam - I'd rather keep nudging you in the right direction till you understand it than hand you finished code. It's the teacher in me... |
||||||||
|
|
|||||||
I was able to enumerate the computers, and have results returned to me!! Regarding the conversion of bytes into Mbytes, can that conversion code be placed into this? And where? HOLY SCHNEYEKEYS!! I got it! |
||||||||
|
|
|||||||
These two lines: Right(' ' + $D_Capacities[$Index], 15) Right(' ' + $D_FreeSpace[$Index], 15) take the capacity and freespace STRING values, left pad them with spaces, and then take the rightmost 15 characters. Thus, it formats and displays in one step. To convert the bytes to K, M, or GBytes, you need to divide the numeric value by the appropriate value. Keep in mind that the byte values are strings, so need to be converted to numbers. Since the actual values could exceed the limits of integer processing, we convert them to doubles, then divide by MB. As I indicated in my prior post, you can replace these lines with my example: Right(' ' + (CDbl($D_Capacities[$Index]) / 1048576.0), 15) Right(' ' + (CDbl($D_FreeSpace[$Index]) / 1048576.0), 15) The byte values are converted to double-precision numbers, divided by 1MB, then appended to a string of 15 spaces, then trimmed to 15 spaces. This "padding" makes the numbers right-justified in a 15-char wide column. Note the ".0" at the end of the 1MB divisor - this assures that the division is DBL / DBL, maintaining precision. Kix automatically converts the result to a string, since a string is the first type being combined with the result of the calculation inside the quotes. Glenn |
||||||||
|
|
|||||||
scratch that...I can not get the all my machines to enuermate in a loop. I keep getting the results of my local machine. Code: Break On ; print the header 'Drv Capacity Free <!>' ? ;===================================================== ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) ; $Computer = 'COMPUTER' If Open(3, "C:\servers.TXT") = 1 $Computer = ReadLine(3) While Not @ERROR ; reporting code goes here... $Computer = ReadLine(3) Loop $ = Close(3) EndIf ;===================================================== ; load the array from the computer $aSysInfo = WMISysInfo($Computer) If UBound($aSysInfo) = -1 'Bad computer name or no access!' ? Quit 1 EndIf ; Examine the disk drives & capacities $D_Letters = Split($aSysInfo[32], ',') $D_Capacities = Split($aSysInfo[33], ',') $D_FreeSpace = Split($aSysInfo[34], ',') For $Index = 0 to UBound($D_Letters) Left($D_Letters[$Index] + ' ', 4) ; 15 spaces between quotes Right(' ' + CDbl($D_Capacities[$Index]) / 1048576.0, 15) Right(' ' + CDbl($D_FreeSpace[$Index]) / 1048576.0, 15) If CDbl($D_FreeSpace[$Index]) < 500000 ' <Low!>' EndIf ? Next |
||||||||
|
|
|||||||
Hmm - seems that is exactly what you asked for! If you call the function with no argument, you get the information from the local computer. You're calling it with $Computer, which is empty. Your loop read the contents of the file, assigning each name to $Computer, but then did nothing with it! The last read, which had no data, cleared $Computer, so when you finally called the WMISysInfo(), it had an empty argument and displayed the results of the local computer (only). Here's what you really need - the code that actually does the work to be inside your enumeration loop! I also modified the error check, so that it complained (but didn't quit) if there was an error accessing the computer. Code: Break On ; print the header 'Drv Capacity Free <!>' ? ;===================================================== ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) ; $Computer = 'COMPUTER' If Open(3, "C:\servers.TXT") = 1 $Computer = ReadLine(3) While Not @ERROR ; reporting code goes here... YES - THE CODE THAT DOES THE WORK!! ; load the array from the computer $aSysInfo = WMISysInfo($Computer) If UBound($aSysInfo) = -1 'Bad computer name or no access! (' $Computer ')' ? Else $Computer ? ; Examine the disk drives & capacities $D_Letters = Split($aSysInfo[32], ',') $D_Capacities = Split($aSysInfo[33], ',') $D_FreeSpace = Split($aSysInfo[34], ',') For $Index = 0 to UBound($D_Letters) Left($D_Letters[$Index] + ' ', 4) ; 15 spaces between quotes Right(' ' + CDbl($D_Capacities[$Index]) / 1048576.0, 15) Right(' ' + CDbl($D_FreeSpace[$Index]) / 1048576.0, 15) If CDbl($D_FreeSpace[$Index]) < 500000 ' <Low!>' EndIf ? Next EndIf $Computer = ReadLine(3) Loop $ = Close(3) EndIf ;===================================================== Glenn |
||||||||
|
|
|||||||
Glenn, I owe you a case of Upstates finest brew! |
||||||||
|
|
|||||||
Upstates? OK - there's still work to be done.. You really should declare your variables, add the usual SetOption parameters that enforce good coding practices, and add plenty of comments, so you will remember the how and why 6 months from now, when you'll need to expand the capabilities to report on CPU type/speed, or some other report that some manager dreams up. I take points off for poorly indented/formatted code, low comment:code ratios, and undeclared variables! Extra points for block comments, and use of PostPrep for presentation formatting. Glenn |
||||||||
|
|
|||||||
Upstate, NY. I can not get a results returned to me right now. Just coming back on screen with blank fields. Code: Break On ; print the header 'Drv Capacity Free <!>' ? ;===================================================== ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) ; $Computer = 'COMPUTER' If Open(3, "C:\servers.TXT") = 1 $Computer = ReadLine(3) While Not @ERROR ; reporting code goes here... YES - THE CODE THAT DOES THE WORK!! ; load the array from the computer $aSysInfo = WMISysInfo($Computer) If UBound($aSysInfo) = -1 'Bad computer name or no access! (' $Computer ')' ? Else $Computer ? ; Examine the disk drives & capacities $D_Letters = Split($aSysInfo[32], ',') $D_Capacities = Split($aSysInfo[33], ',') $D_FreeSpace = Split($aSysInfo[34], ',') For $Index = 0 to UBound($D_Letters) Left($D_Letters[$Index] + ' ', 4) ; 15 spaces between quotes Right(' ' + CDbl($D_Capacities[$Index]) / 1048576.0, 15) Right(' ' + CDbl($D_FreeSpace[$Index]) / 1048576.0, 15) If CDbl($D_FreeSpace[$Index]) < 500000 ' <Low!>' EndIf ? Next EndIf $Computer = ReadLine(3) Loop $ = Close(3) EndIf ;===================================================== ; ========================================================== ; UDF Follows ; ========================================================== ;; ;;====================================================================== ;; ;;FUNCTION WMISysInfo() ;; ;;ACTION Returns an array containing system information ;; from local or remote system ;; ;;AUTHOR Glenn Barnas ;; ;;VERSION 1.0 / 2007/10/20 - First release ;; ;;SYNTAX WMISysInfo([host] [,AuthPtr]) ;; ;;PARAMETERS host - OPTIONAL - name of system to query ;; ;; AuthPtr - OPTIONAL - pre-authenticated WMI object pointer ;; Use WMIAuthentication() udf to create the AuthPtr value ;; AuthPtr is not needed if user has admin rights ;; ;;REMARKS Replaced independent OSInfo and HWInfo UDFs ;; ;;RETURNS 40 element array ;; 0 short/full operating system description ;; 1 kernel description (Win2K, WinXP, Win2K3, Vista) ;; 2 operating system role (workstation, member server, domain controller) ;; 3 operating system service pack level ;; 4 operating system build level ;; 5 uni/multi-processor type ;; 6 Computer Name ;; 7 registered owner,organization ;; 8 Serial Number ;; 9 Install Date - YYYY/MM/DD hh:mm:ss ;; 10 Local Date/Time - YYYY/MM/DD hh:mm:ss ;; 11 Last Boot Time - YYYY/MM/DD hh:mm:ss ;; 12 TimeZone info (Std, Daylight, Bias) ;; 13 Primary Domain Affiliation ;; 14 Installed Hotfix list ;; 15 OS Version (numeric) ;; 16 Future Use ;; 17 O/S Architecture ;; 18 Install Method (Clean, Upgrade, SysPrep) ;; 19 RAM/PageFile Info (location MinSize MaxSize) ;; 20 System Brand ;; 21 System Model ;; 22 System S/N ;; 23 System BIOS Revision ;; 24 Processor Type ;; 25 Processor Speed ;; 26 Processor Count (Physical) ;; 27 Processor Count (Logical) ;; 28 Processor Cores ;; 29 Physical Memory ;; 30 Fixed-Disk Labels, null if none ;; 31 Fixed-Disk Mount Point ("d:\" for drives, path for mounted volumes) (2K3 & higher) ;; 32 Fixed-Disk Drives (A:-Z:, or "MV:" for mounted Volumes) ;; 33 Fixed-Disk Capacities, bytes ;; 34 Fixed-Disk FreeSpace, bytes ;; 35 CD-ROM Disk List ;; 36 Connected Network Drives ;; 37 Hardware Architecture ;; 38 Future Use ;; 39 Future Use ;; ;;DEPENDENCIES WMI support ;; ;;TESTED WITH W2K, WXP, W2K3, Vista, X64 ;; ;;EXAMPLES $Host = '' ;; $aHWI = WMIHWInfo($Host) ;; $Host ' has ' $aHWI[6] ' Physical/Logical processors!' ;; ;; $Host = 'server' ;; $objWMI = WMIAuthenticate('computer', 'userid', 'User-P@ss!') ;; $Up = WMIUptime($Host, $objWMI) ;; 'Secure host ' $Host ' has been up for ' $Up[0] ' days!' ; Function WMISysInfo(OPTIONAL $_Target, OPTIONAL $_pAuth) Dim $objWMIService, $colItems, $objItem ; WMI object vars Dim $_SI[39] ; Var for return array Dim $_, $_Delim, $_SRoot, $_WFile, $_OSVer $_Target = IIf($_Target, $_Target, '.') If InStr($_Target, '\') $_Target = Join(Split($_Target, '\'), '') EndIf If $_pAuth $objWMIService = $_pAuth Else $objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Target + '\root\cimv2') If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf EndIf ; O/S SECTION ####################################################### ; OperatingSystem ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48) For Each $objItem in $colItems $_SRoot = '\\' + $_Target + '\' + Join(Split($objItem.SystemDirectory, ':'), Chr(36)) + '\' $_SI[0] = Trim(Split($objItem.Name, '|')[0]) $_SI[15] = $objItem.Version $_ = _osid($_SI[0], $_SI[15]) ; get kernel name, fix OS name $_SI[0] = $_[0] $_SI[1] = $_[1] $_OSVer = Trim(Join(Split($_SI[15], '.', 2), '.')) $_ = Split($objItem.CSDVersion, ' ') $_SI[3] = $_[UBound($_)] $_SI[4] = $objItem.BuildNumber $_SI[5] = $objItem.BuildType $_SI[6] = $objItem.CSName $_SI[7] = $objItem.RegisteredUser + '/' + $objItem.Organization $_SI[8] = $objItem.SerialNumber ; Translate the following in to standard date strings (yyyy/mm/dd hh:mm:ss) $_ = $objItem.InstallDate $_SI[9] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.LocalDateTime $_SI[10] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.LastBootUpTime $_SI[11] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.OSArchitecture $_SI[17] = IIf($_, $_, '32-bit') Next $colItems = 0 ; Time Zone ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_TimeZone",,48) For Each $objItem in $colItems $_SI[12] = $objItem.StandardName + ' / ' + $objItem.DaylightName + ' / ' + Abs($objItem.Bias) / 60 Next $colItems = 0 ; Domain ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_NTDomain",,48) For Each $objItem in $colItems $_SI[13] = $objItem.DNSForestName + ',' + $objItem.DomainName Next $colItems = 0 ; Hotfixes ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering",,48) For Each $objItem in $colItems If InStr('KQ', Left($objItem.HotFixID, 1)) $_SI[14] = $_SI[14] + ' ' + $objItem.HotFixID EndIf Next $_SI[14] = SubStr($_SI[14], 2) ; trim result $colItems = 0 ; PageFile ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_PageFile",,48) For Each $objItem in $colItems $_SI[19] = $_SI[19] + ' ' + $objItem.EightDotThreeFileName + ' ' + $objItem.InitialSize + ' ' + $objItem.MaximumSize Next $colItems = 0 ; Check for build status $_SI[18] = 'Clean' $_WFile = $_SRoot + Chr(36) + 'winnt' + Chr(36) + '.inf' If Exist($_WFile) If ReadProfileString($_WFile, 'Data', 'StandardServerUpgrade') = 'yes' Or ReadProfileString($_WFile, 'Data', 'WinNtUpgrade') = 'yes' $_SI[18] = 'Upgrade' EndIf If ReadProfileString($_WFile, 'Unattended', 'InstallFilesPath') $_SI[18] = 'SysPrep' EndIf EndIf ; HARDWARE SECTION ####################################################### ; ComputerSystem ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48) For Each $objItem in $colItems $_ = 'Standalone Workstation', 'Member Workstation', 'Standalone Server', 'Member Server', 'Backup Domain Controller', 'Primary Domain Controller' $_SI[2] = $_[Val($objItem.DomainRole)] $_SI[37] = Left($objItem.SystemType, 3) $_SI[20] = $objItem.Manufacturer $_SI[21] = $objItem.Model $_SI[26] = $objItem.NumberOfProcessors $_SI[29] = $objItem.TotalPhysicalMemory $_ = CInt((CDbl($_SI[29]) + 655360.0) / 1048576.0) $_SI[19] = '' + $_ + $_SI[19] Next $colItems = 0 ; BIOS ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_BIOS",,48) For Each $objItem in $colItems $_SI[22] = $objItem.SerialNumber $_Delim = '' For Each $_ in $objItem.BIOSVersion $_SI[23] = $_SI[23] + $_Delim + $_ $_Delim = ',' Next Next $colItems = 0 ; Processor ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_Processor",,48) For Each $objItem in $colItems $_SI[24] = Trim($objItem.Name) $_SI[25] = $objItem.MaxClockSpeed $_SI[27] = $objItem.NumberOfLogicalProcessors $_SI[28] = $objItem.NumberOfCores Next $colItems = 0 ; Disk Storage ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_LogicalDisk",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 ; fixed disk $_SI[30] = $_SI[30] + ',' + $objItem.VolumeName $_SI[31] = $_SI[31] + ',' + $objItem.Caption + '\' $_SI[32] = $_SI[32] + ',' + $objItem.Caption $_SI[33] = $_SI[33] + ',' + $objItem.Size $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf If $objItem.DriveType = 5 ; CD-ROM $_SI[35] = $_SI[35] + ',' + $objItem.Caption EndIf If $objItem.DriveType = 4 ; Network Drive $_SI[36] = $_SI[36] + ',' + $objItem.Caption + '=' + $objItem.ProviderName EndIf Next $colItems = 0 If $_OSVer > 5.1 ; only supported on W2K3 and higher - return mounted volume info $colItems = $objWMIService.ExecQuery("Select * from Win32_Volume",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 And $objItem.DriveLetter = '' $_SI[30] = $_SI[30] + ',' + $objItem.Label $_SI[31] = $_SI[31] + ',' + $objItem.Caption $_SI[32] = $_SI[32] + ',' + 'MV:' $_SI[33] = $_SI[33] + ',' + $objItem.Capacity $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf Next EndIf $colItems = 0 ; trim leading "," from strings For $_ = 30 to 36 $_SI[$_] = SubStr($_SI[$_], 2) Next ; Return the array $WMISysInfo= $_SI Exit 0 EndFunction ; _osid - supporting function ; Identifies the release version (beta, RTM, Preview, etc), defines a "kernel short name", ; and removes special characters from the description string Function _osid($_Vs, $_Vn) Dim $_ Dim $_Srel ; string of release IDs Dim $_Vmaj ; Major version number Dim $_Vmin ; Minor version number Dim $_Vrel ; Release number Dim $_aR[1] ; Short (KernelID) name, Descriptive Name $_ = Split($_Vn + '.0.0', '.', 3) $_Vmaj = Val($_[0]) $_Vmin = Val($_[1]) $_Vrel = $_[2] ; clean up the O/S description string - remove special chars $_Vs = Join(Split($_Vs, Chr(153)), '') ; (tm) $_Vs = Join(Split($_Vs, Chr(169)), '') ; (c) $_Vs = Join(Split($_Vs, Chr(174)), '') ; (r) Select Case $_Vmaj = 5 And $_Vmin = 0 ; Win2K $_aR[1] = 'Win2K' $_Srel = '1515=(Beta 2),2031=(Beta 3),2183=(Beta 3),2128=(Beta 3 RC2),2195=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 5 And $_Vmin = 1 ; WinXP $_aR[1] = 'WinXP' $_Srel = '2505=(RC1),2600=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 5 And $_Vmin = 2 ; Win2K3 $_aR[1] = 'Win2K3' $_Srel = '3718=(Eval),3790=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 6 And $_Vmin = 0 ; Vista $_aR[1] = 'Vista' $_Srel = '6000=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case 1 $_aR[1] = 'Unknown' EndSelect $_aR[0] = $_Vs $_osid = $_aR EndFunction |
||||||||
|
|
|||||||
It is opening servers.txt. What does your servers.txt file looks like? There should be one server on each line so readline only reads one server name each time it reads a line. |
||||||||
|
|
|||||||
Servers.txt Code: CWBCISPMSTR1 CWBCISPCONS1 CWBCISPCONS2 CWBCISPEPI1 CWBCISPELINK1 CWBERMSRV1 CWBCISPELINK1 SWBCISULMS SWBCISPEXTCARE1 CWBCISQMSTR1 CWBCISQCONS1 CWBCISQEPI CWBCISQELINK1 SWBCISQEXTCARE1 SWBCISMASTER SWBCISCONS SWBCISEPI SWBCISELINK SWBCISEXTCARE01 SWBCISMRPTST01 |
||||||||
|
|
|||||||
The problem is two-fold. One error is mine. On the If Open(... line, change the "1" at the end to a "0" If Open(3, "C:\servers.TXT") = 0 This was a typo in my earlier example. The other issue is - the code I posted simply corrected your logic, moving the process logic into the enumeration loop. I did not re-post the UDF part of the code. Once you make the change to the Open statement and add the UDF back into your script, it should work - here's my results with the corrected script: Code: Drv Capacity Free <!> appp04 C: 12001.65234375 7689.5 D: 34326.35546875 30163.34375 E: 13884.30078125 13699.015625 appp05 C: 12001.65234375 7838.58984375 D: 34326.35546875 30164.06640625 E: 13884.30078125 13699.015625 appp06 C: 12001.65234375 9424.59375 D: 5122.28515625 3048.03515625 E: 8762.01171875 8596.80078125 appp07 C: 12001.65234375 7225.30859375 D: 34326.35546875 30167.06640625 E: 13884.30078125 13697.4453125 appp08 C: 12001.65234375 8329.171875 D: 34326.35546875 30167.06640625 E: 13884.30078125 13699.01171875 Considering the large decimals, you'll prolly want to wrap the CDbl(....) in an Int() function, like this - Right(' ' + Int(CDbl($D_Capacities[$Index]) / 1048576.0), 15) Right(' ' + Int(CDbl($D_FreeSpace[$Index]) / 1048576.0), 15) Glenn |
||||||||
|
|
|||||||
PS - you get Extra extra credit for finding the instructors errors! |
||||||||
|
|
|||||||
HA! Yeah, I found it by accident for sure. But it makes sense. The UDF is as follows? Where does this get placed? Code: ; Disk Storage ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_LogicalDisk",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 ; fixed disk $_SI[30] = $_SI[30] + ',' + $objItem.VolumeName $_SI[31] = $_SI[31] + ',' + $objItem.Caption + '\' $_SI[32] = $_SI[32] + ',' + $objItem.Caption $_SI[33] = $_SI[33] + ',' + $objItem.Size $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf If $objItem.DriveType = 5 ; CD-ROM $_SI[35] = $_SI[35] + ',' + $objItem.Caption EndIf If $objItem.DriveType = 4 ; Network Drive $_SI[36] = $_SI[36] + ',' + $objItem.Caption + '=' + $objItem.ProviderName EndIf Next $colItems = 0 If $_OSVer > 5.1 ; only supported on W2K3 and higher - return mounted volume info $colItems = $objWMIService.ExecQuery("Select * from Win32_Volume",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 And $objItem.DriveLetter = '' $_SI[30] = $_SI[30] + ',' + $objItem.Label $_SI[31] = $_SI[31] + ',' + $objItem.Caption $_SI[32] = $_SI[32] + ',' + 'MV:' $_SI[33] = $_SI[33] + ',' + $objItem.Capacity $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf Next EndIf $colItems = 0 ; trim leading "," from strings For $_ = 30 to 36 $_SI[$_] = SubStr($_SI[$_], 2) Next ; Return the array $WMISysInfo= $_SI Exit 0 EndFunction |
||||||||
|
|
|||||||
I'm not sure where you pulled that snippet from ... but it looks like you pulled it from the middle of my UDF. Take the code I posted earlier, make the changes I mentioned, then take the ENTIRE text of the UDF you downloaded earlier (WMISysInfo) and paste it at the end of the script. You CANNOT mess with UDFs - you need to use them as they are, in their entirety. Glenn |
||||||||
|
|
|||||||
This is what it should look like: Code: Break On ; print the header 'Drv Capacity Free <!>' ? ;===================================================== ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) ; $Computer = 'COMPUTER' If Open(3, "C:\servers.TXT") = 0 $Computer = ReadLine(3) While Not @ERROR ; reporting code goes here... YES - THE CODE THAT DOES THE WORK!! ; load the array from the computer $aSysInfo = WMISysInfo($Computer) @SERROR ? UBound($aSysInfo) ? If UBound($aSysInfo) = -1 'Bad computer name or no access! (' $Computer ')' ? Else $Computer ? ; Examine the disk drives & capacities $D_Letters = Split($aSysInfo[32], ',') $D_Capacities = Split($aSysInfo[33], ',') $D_FreeSpace = Split($aSysInfo[34], ',') For $Index = 0 to UBound($D_Letters) Left($D_Letters[$Index] + ' ', 4) ; 15 spaces between quotes Right(' ' + Int(CDbl($D_Capacities[$Index]) / 1048576.0), 15) Right(' ' + Int(CDbl($D_FreeSpace[$Index]) / 1048576.0), 15) If CDbl($D_FreeSpace[$Index]) < 500000 ' <Low!>' EndIf ? Next EndIf $Computer = ReadLine(3) Loop $ = Close(3) Else @SERROR ? EndIf ;===================================================== ; ========================================================== ; UDF Follows ; ========================================================== ;; ;;====================================================================== ;; ;;FUNCTION WMISysInfo() ;; ;;ACTION Returns an array containing system information ;; from local or remote system ;; ;;AUTHOR Glenn Barnas ;; ;;VERSION 1.0 / 2007/10/20 - First release ;; ;;SYNTAX WMISysInfo([host] [,AuthPtr]) ;; ;;PARAMETERS host - OPTIONAL - name of system to query ;; ;; AuthPtr - OPTIONAL - pre-authenticated WMI object pointer ;; Use WMIAuthentication() udf to create the AuthPtr value ;; AuthPtr is not needed if user has admin rights ;; ;;REMARKS Replaced independent OSInfo and HWInfo UDFs ;; ;;RETURNS 40 element array ;; 0 short/full operating system description ;; 1 kernel description (Win2K, WinXP, Win2K3, Vista) ;; 2 operating system role (workstation, member server, domain controller) ;; 3 operating system service pack level ;; 4 operating system build level ;; 5 uni/multi-processor type ;; 6 Computer Name ;; 7 registered owner,organization ;; 8 Serial Number ;; 9 Install Date - YYYY/MM/DD hh:mm:ss ;; 10 Local Date/Time - YYYY/MM/DD hh:mm:ss ;; 11 Last Boot Time - YYYY/MM/DD hh:mm:ss ;; 12 TimeZone info (Std, Daylight, Bias) ;; 13 Primary Domain Affiliation ;; 14 Installed Hotfix list ;; 15 OS Version (numeric) ;; 16 Future Use ;; 17 O/S Architecture ;; 18 Install Method (Clean, Upgrade, SysPrep) ;; 19 RAM/PageFile Info (location MinSize MaxSize) ;; 20 System Brand ;; 21 System Model ;; 22 System S/N ;; 23 System BIOS Revision ;; 24 Processor Type ;; 25 Processor Speed ;; 26 Processor Count (Physical) ;; 27 Processor Count (Logical) ;; 28 Processor Cores ;; 29 Physical Memory ;; 30 Fixed-Disk Labels, null if none ;; 31 Fixed-Disk Mount Point ("d:\" for drives, path for mounted volumes) (2K3 & higher) ;; 32 Fixed-Disk Drives (A:-Z:, or "MV:" for mounted Volumes) ;; 33 Fixed-Disk Capacities, bytes ;; 34 Fixed-Disk FreeSpace, bytes ;; 35 CD-ROM Disk List ;; 36 Connected Network Drives ;; 37 Hardware Architecture ;; 38 Future Use ;; 39 Future Use ;; ;;DEPENDENCIES WMI support ;; ;;TESTED WITH W2K, WXP, W2K3, Vista, X64 ;; ;;EXAMPLES $Host = '' ;; $aHWI = WMIHWInfo($Host) ;; $Host ' has ' $aHWI[6] ' Physical/Logical processors!' ;; ;; $Host = 'server' ;; $objWMI = WMIAuthenticate('computer', 'userid', 'User-P@ss!') ;; $Up = WMIUptime($Host, $objWMI) ;; 'Secure host ' $Host ' has been up for ' $Up[0] ' days!' ; Function WMISysInfo(OPTIONAL $_Target, OPTIONAL $_pAuth) Dim $objWMIService, $colItems, $objItem ; WMI object vars Dim $_SI[39] ; Var for return array Dim $_, $_Delim, $_SRoot, $_WFile, $_OSVer $_Target = IIf($_Target, $_Target, '.') If InStr($_Target, '\') $_Target = Join(Split($_Target, '\'), '') EndIf If $_pAuth $objWMIService = $_pAuth Else $objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Target + '\root\cimv2') If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf EndIf ; O/S SECTION ####################################################### ; OperatingSystem ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48) For Each $objItem in $colItems $_SRoot = '\\' + $_Target + '\' + Join(Split($objItem.SystemDirectory, ':'), Chr(36)) + '\' $_SI[0] = Trim(Split($objItem.Name, '|')[0]) $_SI[15] = $objItem.Version $_ = _osid($_SI[0], $_SI[15]) ; get kernel name, fix OS name $_SI[0] = $_[0] $_SI[1] = $_[1] $_OSVer = Trim(Join(Split($_SI[15], '.', 2), '.')) $_ = Split($objItem.CSDVersion, ' ') $_SI[3] = $_[UBound($_)] $_SI[4] = $objItem.BuildNumber $_SI[5] = $objItem.BuildType $_SI[6] = $objItem.CSName $_SI[7] = $objItem.RegisteredUser + '/' + $objItem.Organization $_SI[8] = $objItem.SerialNumber ; Translate the following in to standard date strings (yyyy/mm/dd hh:mm:ss) $_ = $objItem.InstallDate $_SI[9] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.LocalDateTime $_SI[10] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.LastBootUpTime $_SI[11] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' ' + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':' + SubStr($_, 13, 2) $_ = $objItem.OSArchitecture $_SI[17] = IIf($_, $_, '32-bit') Next $colItems = 0 ; Time Zone ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_TimeZone",,48) For Each $objItem in $colItems $_SI[12] = $objItem.StandardName + ' / ' + $objItem.DaylightName + ' / ' + Abs($objItem.Bias) / 60 Next $colItems = 0 ; Domain ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_NTDomain",,48) For Each $objItem in $colItems $_SI[13] = $objItem.DNSForestName + ',' + $objItem.DomainName Next $colItems = 0 ; Hotfixes ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering",,48) For Each $objItem in $colItems If InStr('KQ', Left($objItem.HotFixID, 1)) $_SI[14] = $_SI[14] + ' ' + $objItem.HotFixID EndIf Next $_SI[14] = SubStr($_SI[14], 2) ; trim result $colItems = 0 ; PageFile ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_PageFile",,48) For Each $objItem in $colItems $_SI[19] = $_SI[19] + ' ' + $objItem.EightDotThreeFileName + ' ' + $objItem.InitialSize + ' ' + $objItem.MaximumSize Next $colItems = 0 ; Check for build status $_SI[18] = 'Clean' $_WFile = $_SRoot + Chr(36) + 'winnt' + Chr(36) + '.inf' If Exist($_WFile) If ReadProfileString($_WFile, 'Data', 'StandardServerUpgrade') = 'yes' Or ReadProfileString($_WFile, 'Data', 'WinNtUpgrade') = 'yes' $_SI[18] = 'Upgrade' EndIf If ReadProfileString($_WFile, 'Unattended', 'InstallFilesPath') $_SI[18] = 'SysPrep' EndIf EndIf ; HARDWARE SECTION ####################################################### ; ComputerSystem ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48) For Each $objItem in $colItems $_ = 'Standalone Workstation', 'Member Workstation', 'Standalone Server', 'Member Server', 'Backup Domain Controller', 'Primary Domain Controller' $_SI[2] = $_[Val($objItem.DomainRole)] $_SI[37] = Left($objItem.SystemType, 3) $_SI[20] = $objItem.Manufacturer $_SI[21] = $objItem.Model $_SI[26] = $objItem.NumberOfProcessors $_SI[29] = $objItem.TotalPhysicalMemory $_ = CInt((CDbl($_SI[29]) + 655360.0) / 1048576.0) $_SI[19] = '' + $_ + $_SI[19] Next $colItems = 0 ; BIOS ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_BIOS",,48) For Each $objItem in $colItems $_SI[22] = $objItem.SerialNumber $_Delim = '' For Each $_ in $objItem.BIOSVersion $_SI[23] = $_SI[23] + $_Delim + $_ $_Delim = ',' Next Next $colItems = 0 ; Processor ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_Processor",,48) For Each $objItem in $colItems $_SI[24] = Trim($objItem.Name) $_SI[25] = $objItem.MaxClockSpeed $_SI[27] = $objItem.NumberOfLogicalProcessors $_SI[28] = $objItem.NumberOfCores Next $colItems = 0 ; Disk Storage ======================================================= $colItems = $objWMIService.ExecQuery("Select * from Win32_LogicalDisk",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 ; fixed disk $_SI[30] = $_SI[30] + ',' + $objItem.VolumeName $_SI[31] = $_SI[31] + ',' + $objItem.Caption + '\' $_SI[32] = $_SI[32] + ',' + $objItem.Caption $_SI[33] = $_SI[33] + ',' + $objItem.Size $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf If $objItem.DriveType = 5 ; CD-ROM $_SI[35] = $_SI[35] + ',' + $objItem.Caption EndIf If $objItem.DriveType = 4 ; Network Drive $_SI[36] = $_SI[36] + ',' + $objItem.Caption + '=' + $objItem.ProviderName EndIf Next $colItems = 0 If $_OSVer > 5.1 ; only supported on W2K3 and higher - return mounted volume info $colItems = $objWMIService.ExecQuery("Select * from Win32_Volume",,48) For Each $objItem in $colItems If $objItem.DriveType = 3 And $objItem.DriveLetter = '' $_SI[30] = $_SI[30] + ',' + $objItem.Label $_SI[31] = $_SI[31] + ',' + $objItem.Caption $_SI[32] = $_SI[32] + ',' + 'MV:' $_SI[33] = $_SI[33] + ',' + $objItem.Capacity $_SI[34] = $_SI[34] + ',' + $objItem.FreeSpace EndIf Next EndIf $colItems = 0 ; trim leading "," from strings For $_ = 30 to 36 $_SI[$_] = SubStr($_SI[$_], 2) Next ; Return the array $WMISysInfo= $_SI Exit 0 EndFunction ; _osid - supporting function ; Identifies the release version (beta, RTM, Preview, etc), defines a "kernel short name", ; and removes special characters from the description string Function _osid($_Vs, $_Vn) Dim $_ Dim $_Srel ; string of release IDs Dim $_Vmaj ; Major version number Dim $_Vmin ; Minor version number Dim $_Vrel ; Release number Dim $_aR[1] ; Short (KernelID) name, Descriptive Name $_ = Split($_Vn + '.0.0', '.', 3) $_Vmaj = Val($_[0]) $_Vmin = Val($_[1]) $_Vrel = $_[2] ; clean up the O/S description string - remove special chars $_Vs = Join(Split($_Vs, Chr(153)), '') ; (tm) $_Vs = Join(Split($_Vs, Chr(169)), '') ; (c) $_Vs = Join(Split($_Vs, Chr(174)), '') ; (r) Select Case $_Vmaj = 5 And $_Vmin = 0 ; Win2K $_aR[1] = 'Win2K' $_Srel = '1515=(Beta 2),2031=(Beta 3),2183=(Beta 3),2128=(Beta 3 RC2),2195=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 5 And $_Vmin = 1 ; WinXP $_aR[1] = 'WinXP' $_Srel = '2505=(RC1),2600=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 5 And $_Vmin = 2 ; Win2K3 $_aR[1] = 'Win2K3' $_Srel = '3718=(Eval),3790=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case $_Vmaj = 6 And $_Vmin = 0 ; Vista $_aR[1] = 'Vista' $_Srel = '6000=(RTM)' $_ = InStr($_Srel, $_VRel) If $_ $_ = Split(SubStr($_Srel, $_ + 5), ',')[0] $_Vs = $_Vs + ' ' + $_ EndIf Case 1 $_aR[1] = 'Unknown' EndSelect $_aR[0] = $_Vs $_osid = $_aR EndFunction |
||||||||
|
|
|||||||
Glenn, thanks again for all your assistance. I am sorry that it pretty much had to be spoon-fed to me. But I have learn quite a bit about the power of scripting. One last caveat of this is that I am trying to include the volume name. Here is what I tried, but with no results. Code: Break On ; print the header 'Drv Label Capacity Free <!>' ? ;===================================================== ; Define the name of your test computer ; (later, enumerate a list of computers in a loop) ; $Computer = 'COMPUTER' If Open(3, "C:\servers.TXT") = 0 $Computer = ReadLine(3) While Not @ERROR ; reporting code goes here... YES - THE CODE THAT DOES THE WORK!! ; load the array from the computer $aSysInfo = WMISysInfo($Computer) @SERROR ? UBound($aSysInfo) ? If UBound($aSysInfo) = -1 'Bad computer name or no access! (' $Computer ')' ? Else $Computer ? ; Examine the disk drives & capacities $D_Letters = Split($aSysInfo[32], ',') $D_VolumeName = Split($aSysInfo[30], ',') $D_Capacities = Split($aSysInfo[33], ',') $D_FreeSpace = Split($aSysInfo[34], ',') For $Index = 0 to UBound($D_Letters) Left($D_Letters[$Index] + ' ', 4) ; 15 spaces between quotes Right(' ' + Int(CDbl($D_Capacities[$Index]) / 1048576.0), 15) Right(' ' + Int(CDbl($D_FreeSpace[$Index]) / 1048576.0), 15) If CDbl($D_FreeSpace[$Index]) < 500000 ' <Low!>' EndIf ? Next EndIf $Computer = ReadLine(3) Loop $ = Close(3) Else @SERROR ? EndIf |
||||||||
|
|
|||||||
No problem - we're here because we enjoy this. You, however, do have one small problem.. Let me try to clarify a bit. "$aSysInfo" is a array, basically a list of related data accessed by an index. Think of one column in a spreadsheet - a variable called $COL_A contains data in 20 rows. In Excel, the rows are numbered 1-20, but in Kix (and most programming languages) arrays are numbered 0-19. This is called "Zero-Based". Think of the $aSysInfo in terms of a column in a spreadsheet for a moment. Cells 30-34 contain lists of information about drives - "C:,D:,E:" in one, and "14981948109,12390419843,13893049" in the next. Thus, your brain can associate the C: with 14981948109 bytes in the next row; D: with 12390419843, and so on. The computer needs to do it a bit differently. The section of your code that looks like $D_Letters = Split($aSysInfo[32], ',') takes the comma-delimited text string from the 32nd array element and creates a new array called D_Letters. Each element in this array has one drive letter. Since we're doing that for each of these lists, we have several arrays. (consider the spreadsheet, where columns M, N, O, and P represent these vars, and rows 1-3 represent the values. So M1 holds "C:", N1 holds the capacity, O1 holds the freespace, and so on..) I see that you added a new array $D_VolumeName. This - in effect - altered the spreadsheet model by inserting a new column, but your new column is "hidden". Right after we split the drive data strings into individual arrays, we assume that $D_Letters contains one element for each drive letter. Using a For/Next loop, we iterate all of the element values of the drive data arrays using the $Index var. Right after the "For $Index" line are statements that format and output the various array values (note that each one is referenced as $arrayname[$INDEX]). Each of these lines pad the array value with spaces, but then trim it to a specific length. What you're missing is a reference to the new array you created. If you use the first line as a model, you should be able to add the labels the same way, although you'll need to adjust the spacing of the header as well. Each column is 15 chars wide. < Stop reading here if you want to think about the solution yourself > So - bottom line - you've correctly referenced the VolumeLabels string from the array, and split it into individual items, but you haven't output it. Copy the "Left($D_Letters".. line, paste a new copy below it, and change the var name to $D_VolumeName and you should be good to go. Glenn |
||||||||
|
|
|||||||
Glenn....you magnificent bastard!!! Ok, I challenged myself and fixed it. |
||||||||
|
|
|||||||
Originally Posted By: rcurrao Glenn....you magnificent bastard!!! I believe the term around here is "Basta" Originally Posted By: rcurrao Ok, I challenged myself and fixed it. Sweet! Now I can tell you that I have a utility that collects this information from key servers every evening, and emails a healthcheck report to various admins each morning. It's more comprehensive than this, but based on the same UDF (and many others, too). I've extended my script to also report on scheduled tasks, key services, & missing critical hotfixes. It also scans the event logs and summarizes warning/error events so you don't have to review dozens or hundreds of servers to be alerted of problems. Glenn |
||||||||
|
|
|||||||
hey glenn, this util of yours... does it run on single server collecting data from others or does it have a client side that can be distributed around the world? |
||||||||
|
|
|||||||
Um - yes? The event log part runs on the client, dumping the logs each night - part of an archiving requirement we have. Keeps 30 days of .EVT files on the server. It also exports on the local server to a TXT format. Exporting on the local computer maintains the computer-specific messages. There's a server component that gathers some basic info, along with the exported event logs from the servers. After gathering the data, another process is triggered to generate the reports and send the emails. It's a snapshot of system health, along with a summary of the past 24 hours of the event logs, with all the crap filtered out. Each line in the event log report lists the event ID, how many times it occurred, and displays one random message (ie - if event 123 occurred 47 times, the process picks one of the 47 error 123 events at random to include in the email. The point is to give the admin a clue of how many times a certain kind of message has appeared, and let them determine if a closer examination is needed. When I was at the Fed, we gathered info from about 100 key servers in several sites around the country. A few connected by T3, but some by T1. Data collection ran on a Compaq DL-380 G1 w/ a single 800MHz processor, and performed most of the collections in about 15 minutes at 100% CPU load. It pulled data from a few very old systems at poorly connected sites, which took about 20-30 minutes to complete. Depends on how many entries there are in the event logs, and the speed of the links, remote computers, etc.. We currently collect data from about 40 servers in two well-connected sites in about 4-5 minutes at 100% load. About the 100% load - I wrote the process to multi-thread the collections - as many as 35 at a time running independently. I kick off 25, then wait until only 10 processes remain and kick off 25 more.. The idea was to hammer the collection server to get it done as quickly as possible. There actually is a client-side component that I developed for use in DMZ servers. The client was executed over SSH, and returned all of the data. It could easily be adapted to a full client/server environment. I chose not to because we had restrictions about installing client software. I can send you a sample report from my home network if you PM me your email. Glenn |
||||||||
|
|
|||||||
Wow!! That is progressive...but as Freakin Sweet! I wanted to know the possibilities on the reporting output. Is there a way I can get the "Total Capacity" and "total Free Space" MB's for particular volume labels (e.g. data) to be added up and divided by 1024 to produce a GB value? I may be wishing here. |