Extending the Computer Inventory to Support User Profile Specific & Other Non-Inventoried Data
Extending the Dell KACE K1000 System Management Appliance's Computer Inventory to Support User Profile Specific & Other Non-Inventoried Data
John C. Verbosky
Helpdesk Coordinator
Resco Products, Inc.
_________________________________________________________________________________
Hopefully all of this will help to clarify what is covered in my presentation, so that you can use this in your organization.ÂÂÂ
Note - The ShellCommandTextReturn listed in step 5 below works in versions prior to 5.1 and post 5.3.47173. The other versions (5.2 and earlier 5.3) have a bug that prevent this command from working properly.
Note - I'm not a scripting wizard and most of the scripts have been cobbled together via examples found via Google (along with a lot of trial & error testing). I've tried to ensure that nothing hangs or crashes, but if you see things that can be improved, please share.
Note - There's a bug in the reports where the line breaks are not processed correctly during the text file import and they end up listed in the reports rather than being line breaks. Tyler Gingrich has fixed this in the Computer Inventory screen so the results are clean, but the reports still exhibit this. They are still usable, just an FYI.
_________________________________________________________________________________
_________________________________________________________________________________
Custom Inventory Items & Reporting for Scripts
1) Create a custom folder on all PCs for holding script output files (i.e. C:\Windows\KBOX)
 - this can be done using a vbs script and run from KBOX
2) Create a vbs script that outputs to a text file to a custom folder (i.e. C:\Windows\KBOX)
 - create cleanup routine in script for output file as necessary
3) Create a new item in Scripts - Scripts to deploy (see Scripting Settings for VBS Scripts below line break for ref)
4) Run/deploy script on a test PC and make sure file is output correctly to custom folder
5) Create a new Inventory - Software item
 Example:
 - Display Name      Screen Resolution
 - Custom Inv Rule   ShellCommandTextReturn(cmd /c type c:\WINDOWS\KBOX\screen_resolution.txt)
6) Force inventory update on a the test PC via Inventory - Computers screen
7) Check test PC's Custom Inventory Field to verify it is populated with text from script output file
8) Create a new report using Report Wizard
ÂÂÂ
Example (old style reports):
- Report Title/Category & Description   anything
- Choose your topic         Computer
*next*
- Display Columns
   Computer Identity Information.System Name
   Computer Identity Information.IP Address
   Custom Fields.Screen Resolution
*next*
*next* (no rules)
- OrderBy Columns
   Computer Identity Information.System Name
*next*
- click on *(Report Name)* and adjust page size, etc
- click on column headers and rename as desired
*save*
9) Run new report - should list all computers and have entry for test PC with text from script output file.
_________________________________________________________________________________
_________________________________________________________________________________
Scripting Settings for VBS Scripts
_________________________________________________________________________________
To create a scripting item using a vbs script:
1) Script Type      Offline KScript (or Online KScript if script needs to run as logged in user)
2) Enabled      checkbox has to be checked
3) Deployment      Specify one of these (all, specific PCs, label)
4) Supported OS    Microsoft Windows
5) Run As      Run As User logged in to console (if script needs to run as logged in user)
      * note - needs to have trap in vbs script for when no one logged into PC
6) Dependencies     Upload target vbs script here
7) Policy or Job Rules
Task 1
 Attempts   1
 On Failure   Break
 Verify      Always Fail
 Remediation
 On Success  ÂÂÂ
1) Launch a program
  Directory      $(KBOX_SYS_DIR)
  File         cscript.exe
  Check box for "Wait for startup" (yes)
  Parameters      "$(KACE_DEPENDENCY_DIR)\screen_resolution.vbs" (for example)
(optional - if you want to upload files to the kbox - be aware you can't report on these)
2) Upload a file
  Directory      Wherever vbs script outputs file (i.e. C:\Windows\KBOX)
      File         name of output file (i.e. screen_resolution.txt)
 On Remediation Success
Log message
  successfully ran screen_resolution script
 On Remediation Failure
Log message
  failed to run screen_resolution script
8) Save
_________________________________________________________________________________
_________________________________________________________________________________
Scripts shown in the presentation and used in my environment
All scripts are set to check for the presence of C:\Windows\KBOX, create it if it's not present, run the applicable WMI query, and output it to a text file.
_________________________________________________________________________________
_________________________________________________________________________________
screen_resolution.vbs
_________________________________________________________________________________
Dim objFSO, newfolder
Dim strComputer, objWMIService
Dim fso, fsHandle, objShell, LogFileName, colItems, objItem
set objFSO=CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists("c:\Windows\KBOX") Then
newfolder = objFSO.CreateFolder ("c:\Windows\KBOX")
End If
Set objShell = CreateObject("Wscript.Shell")
Set fso = Wscript.CreateObject("Scripting.FilesystemObject")
If objFSO.FileExists("c:\Windows\KBOX\screen_resolution.txt") Then
fso.DeleteFile "c:\windows\KBOX\screen_resolution.txt", True
End If
LogFileName= "C:\Windows\KBOX\screen_resolution.txt"
set fsHandle = fso.OpenTextFile (LogFileName,8,True)
Set objWMIService = GetObject("Winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_DesktopMonitor where DeviceID = 'DesktopMonitor1'",,0)
For Each objItem in colItems
intHorizontal = objItem.ScreenWidth
intVertical = objItem.ScreenHeight
fsHandle.Writeline intHorizontal & " * " & intVertical _
fsHandle.Writeblanklines 1
fsHandle.close
set objShell = Nothing
set fso = Nothing
Next
_________________________________________________________________________________
_________________________________________________________________________________
local_and_network_drives.vbs
_________________________________________________________________________________
Dim objFSO, newfolder
Dim strComputer, objWMIService
Dim fso, fsHandle, objShell,LogFileName, colItems, objItem
set objFSO=CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists("c:\Windows\KBOX") Then
newfolder = objFSO.CreateFolder ("c:\Windows\KBOX")
End If
Set objShell = CreateObject("Wscript.Shell")
Set fso = Wscript.CreateObject("Scripting.FilesystemObject")
If objFSO.FileExists("c:\Windows\KBOX\local_and_network_drives.txt") Then
fso.DeleteFile "c:\windows\KBOX\local_and_network_drives.txt", True
End If
LogFileName= "C:\Windows\KBOX\local_and_network_drives.txt"
set fsHandle = fso.OpenTextFile (LogFileName,8,True)
sUser = ConsoleUser(".") ' use "." for local computer
Function ConsoleUser(sHost)
' Returns name of user logged on to console
' If no users are logged on, returns ""
Dim oWMI, colProc, oProcess, sUser, sDomain
Set oWmi = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate,(debug)}!\\" _
& sHost & "\root\cimv2")
Set colProc = oWmi.ExecQuery("Select Name from Win32_Process" _
& " Where Name='explorer.exe' and SessionID=0")
ConsoleUser = ""
For Each oProcess In colProc
lRet = oProcess.GetOwner(sUser, sDomain)
If lRet = 0 Then
ConsoleUser = sUser
End If
Next
End Function
fsHandle.Writeline Now & " - " _
& "Logged in user: " & suser _
fsHandle.Writeline "------------------------------------------------------"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDrives = objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where DriveType = 3")
For Each objDrive in colDrives
fsHandle.Writeline objDrive.Name & " " & "Local Hard Drive"
Next
Set colDrives = objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where DriveType = 5")
For Each objDrive in colDrives
fsHandle.Writeline objDrive.Name & " " & "CD/DVD Drive"
Next
Set colDrives = objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where DriveType = 4")
For Each objDrive in colDrives
fsHandle.Writeline objDrive.Name & " " & objDrive.ProviderName _
Next
fsHandle.Writeblanklines 1
fsHandle.close
set objShell = Nothing
set fso = Nothing
_________________________________________________________________________________
_________________________________________________________________________________
memory_info.vbs
_________________________________________________________________________________
Dim objFSO, newfolder
Dim strComputer, objWMIService
Dim fso, fsHandle, objShell,LogFileName, colItems, objItem
set objFSO=CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists("c:\Windows\KBOX") Then
newfolder = objFSO.CreateFolder ("c:\Windows\KBOX")
End If
Set objShell = CreateObject("Wscript.Shell")
Set fso = Wscript.CreateObject("Scripting.FilesystemObject")
If objFSO.FileExists("c:\Windows\KBOX\memory_info.txt") Then
fso.DeleteFile "c:\windows\KBOX\memory_info.txt", True
End If
LogFileName= "C:\Windows\KBOX\memory_info.txt"
set fsHandle = fso.OpenTextFile (LogFileName,8,True)
fsHandle.Writeline "------------------------------------------------------"
fsHandle.Writeline Now
fsHandle.Writeline "------------------------------------------------------"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_PhysicalMemoryArray")
For Each objItem in colItems
fsHandle.Writeline "Slots:               " & objItem.MemoryDevices
fsHandle.Writeline "Maximum Capacity:    " & (objItem.MaxCapacity / 1024) & " MB"
fsHandle.Writeline "------------------------------------------------------"
Next
Set col2Items = objWMIService.ExecQuery("Select * from Win32_PhysicalMemory")
For Each objItem in col2Items
Dim ff, mt
If objItem.FormFactor = 0 THEN
ff = "Unknown"
ElseIf objItem.FormFactor = 1 THEN
ff = "Other"
ElseIf objItem.FormFactor = 2 THEN
ff = "SIP"
ElseIf objItem.FormFactor = 3 THEN
ff = "DIP"
ElseIf objItem.FormFactor = 4 THEN
ff = "ZIP"
ElseIf objItem.FormFactor = 5 THEN
ff = "SOJ"
ElseIf objItem.FormFactor = 6 THEN
ff = "Proprietary"
ElseIf objItem.FormFactor = 7 THEN
ff = "SIMM"
ElseIf objItem.FormFactor = 8 THEN
ff = "DIMM"
ElseIf objItem.FormFactor = 9 THEN
ff = "TSOP"
ElseIf objItem.FormFactor = 10 THEN
ff = "PGA"
ElseIf objItem.FormFactor = 11 THEN
ff = "RIMM"
ElseIf objItem.FormFactor = 12 THEN
ff = "SODIMM"
ElseIf objItem.FormFactor = 13 THEN
ff = "SRIMM"
ElseIf objItem.FormFactor = 14 THEN
ff = "SMD"
ElseIf objItem.FormFactor = 15 THEN
ff = "SSMP"
ElseIf objItem.FormFactor = 16 THEN
ff = "QFP"
ElseIf objItem.FormFactor = 17 THEN
ff = "TQFP"
ElseIf objItem.FormFactor = 18 THEN
ff = "SOIC"
ElseIf objItem.FormFactor = 19 THEN
ff = "LCC"
ElseIf objItem.FormFactor = 20 THEN
ff = "PLCC"
ElseIf objItem.FormFactor = 21 THEN
ff = "BGA"
ElseIf objItem.FormFactor = 22 THEN
ff = "FPBGA"
ElseIf objItem.FormFactor = 23 THEN
ff = "LGA"
End If
If objItem.MemoryType = 0 THEN
mt = "Unknown"
ElseIf objItem.MemoryType = 1 THEN
mt = "Other"
ElseIf objItem.MemoryType = 2 THEN
mt = "SIP"
ElseIf objItem.MemoryType = 3 THEN
mt = "DIP"
ElseIf objItem.MemoryType = 4 THEN
mt = "ZIP"
ElseIf objItem.MemoryType = 5 THEN
mt = "SOJ"
ElseIf objItem.MemoryType = 6 THEN
mt = "Proprietary"
ElseIf objItem.MemoryType = 7 THEN
mt = "SIMM"
ElseIf objItem.MemoryType = 8 THEN
mt = "DIMM"
ElseIf objItem.MemoryType = 9 THEN
mt = "TSOP"
ElseIf objItem.MemoryType = 10 THEN
mt = "PGA"
ElseIf objItem.MemoryType = 11 THEN
mt = "RIMM"
ElseIf objItem.MemoryType = 12 THEN
mt = "SODIMM"
ElseIf objItem.MemoryType = 13 THEN
mt = "SRIMM"
ElseIf objItem.MemoryType = 14 THEN
mt = "SMD"
ElseIf objItem.MemoryType = 15 THEN
mt = "SSMP"
ElseIf objItem.MemoryType = 16 THEN
mt = "QFP"
ElseIf objItem.MemoryType = 17 THEN
mt = "TQFP"
ElseIf objItem.MemoryType = 18 THEN
mt = "SOIC"
ElseIf objItem.MemoryType = 19 THEN
mt = "LCC"
ElseIf objItem.MemoryType = 20 THEN
mt = "PLCC"
ElseIf objItem.MemoryType = 21 THEN
mt = "BGA"
ElseIf objItem.MemoryType = 22 THEN
mt = "FPBGA"
ElseIf objItem.MemoryType = 23 THEN
mt = "LGA"
End If
fsHandle.Writeline "Memory Stick:        " & objItem.DeviceLocator
fsHandle.Writeline "Capacity:            " & (objItem.Capacity / 1024 / 1024) & " MB"
fsHandle.Writeline "Form Factor:         " & ff
fsHandle.Writeline "Memory Type:         " & mt
fsHandle.Writeline "Speed:               " & objItem.Speed & " MHz"
fsHandle.Writeline "Data Width:          " & objItem.DataWidth
fsHandle.Writeline "------------------------------------------------------"
Next
fsHandle.Writeblanklines 1
fsHandle.close
set objShell = Nothing
set fso = Nothing
_________________________________________________________________________________
_________________________________________________________________________________
printers_list.vbs (note - my original script was revised by billprew from ExpertsExchange so that it updates users' printers lists while scrubbing old entries)
_________________________________________________________________________________
' Script reads a current log file of users and printers, elliminates dupes,
' adds in the current user and their printers, and then rewrites the log file.
'
' This script uses a dictionary object to store the printers for each user.
' There will be one dictionary item per user, and then the "data" of that
' user's dictionary item will have the format:
'
' date-string|printer 1|printer 2|printer 3|...|
' Require variables to be defined before usage
Option Explicit
' Define constants
Const ForReading = 1
Const ForWriting = 2
' Define variable used in mainline of script
Dim strBaseDir, strListFile, objFSO, dicUsers
' Define base folder and log file name
strBaseDir = "C:\Windows\KBOX\"
strListFile = strBaseDir & "printers_list.txt"
' Create needed objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set dicUsers = CreateObject("Scripting.Dictionary")
' Create the base folder if it doesn't exist
If Not objFSO.FolderExists(strBaseDir) Then
objFSO.CreateFolder(strBaseDir)
End If
' If we have a prior log file, load the users and printers from it first
If objFSO.FileExists(strListFile) Then
GetHistory(strListFile)
End If
' Add printers for the current user to the dictionary
GetPrinters(GetUser("."))
' Dump the contents of the dictionary to the log file
WriteLog(strListFile)
' Subroutnie to load prior history, elliminate any duplicates
Sub GetHistory(strFile)
Dim objFile, strUser, strLine, arrTemp
' Open the log file for reading
Set objFile = objFSO.OpenTextFile(strFile, ForReading)
strUser = ""
' Read each line, looking for user or printer lines, skip blank and dash lines
Do Until objFile.AtEndOfStream
   strLine = objFile.ReadLine
   If strLine <> "" And Mid(strLine, 1, 10) <> "----------" Then
       If Instr(strLine, "Logged in user:") Then
           arrTemp = Split(Replace(strLine, " ", " "), " ")
           strUser = arrTemp(7)
           ' Try to add this user to the dictionary
           AddUser strUser, arrTemp(0) & " " & arrTemp(1) & " " & arrTemp(2)
       Else
           If strUser <> "" Then
               ' Try to add this printer to the dictionary
               AddPrinter strUser, strLine
           End If
       End If
   End If
Loop
objFile.Close
Set objFile = Nothing
End Sub
' Subroutine to get all pronters for this user and add to dictionary
Sub GetPrinters(strUser)
Dim strComputer, objWMI, colPrinters, objPrinter
' Make sure we have a user
If strUser <> "" Then
   ' Add this user to the dictionary if needed
   AddUser strUser, FormatDateTime(Now)
   ' Identify all printers for this user
   strComputer = "."
   Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
   Set colPrinters = objWMI.ExecQuery("Select * from Win32_Printer")
   For Each objPrinter in colPrinters
       ' Try to add each printer to dictionary
       AddPrinter strUser, objPrinter.Name
   Next
   Set colPrinters = Nothing
   Set objWMI = Nothing
End If
End Sub
' Subroutine to dump the accumulated data from the dictionary to the log file
Sub WriteLog(strFile)
Dim objFile, strUser, arrData, i
' Open the log file for writing
Set objFile = objFSO.OpenTextFile (strListFile, ForWriting, True)
' Process each user in the dictionary
For Each strUser in dicUsers
   arrData = Split(dicUsers.Item(strUser), "|")
   ' Header lines for a user
   objFile.Writeline arrData(0) & " - " & "Logged in user: " & strUser
   objFile.Writeline "------------------------------------------------------"
   ' Loop through all printers for this user and write to log file
   If UBound(arrData) > 0 Then
       For i = 1 to UBound(arrData)-1
           objFile.Writeline arrData(i)
       Next
   End If
   objFile.WriteBlankLines 1
Next
objFile.Close
Set objFile = Nothing
End Sub
' Function to get the current user id
Function GetUser(strHost)
' Returns name of user logged on to console
' If no users are logged on, returns ""
Dim objWMI, colProc, objProcess, strUser, strDomain, intReturn
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate,(debug)}!\\" & strHost & "\root\cimv2")
Set colProc = objWMI.ExecQuery("Select Name from Win32_Process Where Name='explorer.exe' and SessionID=0")
GetUser = ""
For Each objProcess In colProc
   intReturn = objProcess.GetOwner(strUser, strDomain)
   If intReturn = 0 Then
       GetUser = strUser
   End If
Next
Set colProc = Nothing
Set objWMI = Nothing
End Function
' Subroutine to add a user to the dictionary (if it doesn't already exist)
Sub AddUser(strUser, strDate)
If dicUsers.Exists(strUser) Then
   dicUsers.Item(strUser) = strDate & "|"
Else
   dicUsers.Add strUser, strDate & "|"
End If
End Sub
' Subroutine to add a printer to the dictionary for a user (if it doesn't already exist)
Sub AddPrinter(strUser, strPrinter)
Dim strTemp
strTemp = dicUsers.Item(strUser)
If Instr(strTemp, "|" & strPrinter & "|") = 0 Then
   dicUsers.Item(strUser) = strTemp & strPrinter & "|"
End If
End Sub
_________________________________________________________________________________
_________________________________________________________________________________
printer_default.vbs (note - this is my reworking of billprew's script so that it captures the default printer)
_________________________________________________________________________________
' Script reads a current log file of users and printers, elliminates dupes,
' adds in the current user and the default printer, and then rewrites the log file.
'
' This script uses a dictionary object to store the printer for each user.
' There will be one dictionary item per user, and then the "data" of that
' user's dictionary item will have the format:
'
' date-string|printer 1|printer 2|printer 3|...|
' Require variables to be defined before usage
Option Explicit
' Define constants
Const ForReading = 1
Const ForWriting = 2
' Define variable used in mainline of script
Dim strBaseDir, strListFile, objFSO, dicUsers
' Define base folder and log file name
strBaseDir = "C:\Windows\KBOX\"
strListFile = strBaseDir & "printer_default.txt"
' Create needed objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set dicUsers = CreateObject("Scripting.Dictionary")
' Create the base folder if it doesn't exist
If Not objFSO.FolderExists(strBaseDir) Then
objFSO.CreateFolder(strBaseDir)
End If
' If we have a prior log file, load the users and printers from it first
If objFSO.FileExists(strListFile) Then
GetHistory(strListFile)
End If
' Add printers for the current user to the dictionary
GetPrinters(GetUser("."))
' Dump the contents of the dictionary to the log file
WriteLog(strListFile)
' Subroutnie to load prior history, elliminate any duplicates
Sub GetHistory(strFile)
Dim objFile, strUser, strLine, arrTemp
' Open the log file for reading
Set objFile = objFSO.OpenTextFile(strFile, ForReading)
strUser = ""
' Read each line, looking for user or printer lines, skip blank and dash lines
Do Until objFile.AtEndOfStream
   strLine = objFile.ReadLine
   If strLine <> "" And Mid(strLine, 1, 10) <> "----------" Then
       If Instr(strLine, "Logged in user:") Then
           arrTemp = Split(Replace(strLine, " ", " "), " ")
           strUser = arrTemp(7)
           ' Try to add this user to the dictionary
           AddUser strUser, arrTemp(0) & " " & arrTemp(1) & " " & arrTemp(2)
       Else
           If strUser <> "" Then
               ' Try to add this printer to the dictionary
               AddPrinter strUser, strLine
           End If
       End If
   End If
Loop
objFile.Close
Set objFile = Nothing
End Sub
' Subroutine to get default printer for this user and add to dictionary
Sub GetPrinters(strUser)
Dim strComputer, objWMI, colPrinters, objPrinter
' Make sure we have a user
If strUser <> "" Then
   ' Add this user to the dictionary if needed
   AddUser strUser, FormatDateTime(Now)
   ' Identify all printers for this user
   strComputer = "."
   Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
   Set colPrinters = objWMI.ExecQuery("Select * from Win32_Printer where Default = 'True'")
   For Each objPrinter in colPrinters
       ' Try to add each printer to dictionary
       AddPrinter strUser, objPrinter.Name
   Next
   Set colPrinters = Nothing
   Set objWMI = Nothing
End If
End Sub
' Subroutine to dump the accumulated data from the dictionary to the log file
Sub WriteLog(strFile)
Dim objFile, strUser, arrData, i
' Open the log file for writing
Set objFile = objFSO.OpenTextFile (strListFile, ForWriting, True)
' Process each user in the dictionary
For Each strUser in dicUsers
   arrData = Split(dicUsers.Item(strUser), "|")
   ' Header lines for a user
   objFile.Writeline arrData(0) & " - " & "Logged in user: " & strUser
   objFile.Writeline "------------------------------------------------------"
   ' Loop through all printers for this user and write to log file
   If UBound(arrData) > 0 Then
       For i = 1 to UBound(arrData)-1
           objFile.Writeline arrData(i)
       Next
   End If
   objFile.WriteBlankLines 1
Next
objFile.Close
Set objFile = Nothing
End Sub
' Function to get the current user id
Function GetUser(strHost)
' Returns name of user logged on to console
' If no users are logged on, returns ""
Dim objWMI, colProc, objProcess, strUser, strDomain, intReturn
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate,(debug)}!\\" & strHost & "\root\cimv2")
Set colProc = objWMI.ExecQuery("Select Name from Win32_Process Where Name='explorer.exe' and SessionID=0")
GetUser = ""
For Each objProcess In colProc
   intReturn = objProcess.GetOwner(strUser, strDomain)
   If intReturn = 0 Then
       GetUser = strUser
   End If
Next
Set colProc = Nothing
Set objWMI = Nothing
End Function
' Subroutine to add a user to the dictionary (if it doesn't already exist)
Sub AddUser(strUser, strDate)
If dicUsers.Exists(strUser) Then
   dicUsers.Item(strUser) = strDate & "|"
Else
   dicUsers.Add strUser, strDate & "|"
End If
End Sub
' Subroutine to add a printer to the dictionary for a user (if it doesn't already exist)
Sub AddPrinter(strUser, strPrinter)
Dim strTemp
strTemp = dicUsers.Item(strUser)
If Instr(strTemp, "|" & strPrinter & "|") = 0 Then
   dicUsers.Item(strUser) = strTemp & strPrinter & "|"
End If
End Sub
_________________________________________________________________________________
_________________________________________________________________________________
Results in Computer Inventory screen:
Answers (40)
Workaround for Line Break Character Bug in Reports Generated on Inventory Custom Fields
John
Many ways to skin a cat and I like your methods. I used the registry in the faq example so that we weren't doing so much during inventory and the data would be prepared for inventory. You could also pipe it to a text file and shellcommandtextreturn that file.
I wrote these scripts for Windows XP, which is what the majority of my machines are running. I haven't tried running them on Windows Vista/7, so if that's what you are using the WMI calls or writeline part of the script may need adjusted for these OSes. If the script is creating blank text files, that would indicate that the script is running to some degree (I'm assuming to the point of creating the C:\Windows\KBOX folder and the text file with the correct name sections are working?). If you know any scripting (or have time to play a bit), you could try removing the writeline section and use a message prompt output instead - this would give you a relatively quick way of determining if the WMI calls part is where the script is failing or if it's just the writeline calls (of course, it could be both, but this would allow you to verify this). Most of the example code I found on the various vbscript sites used the message prompt method to output script results, so hopefully this will be fairly straightforward. When testing, I wouldn't worry about formatting - just see if anything is output.
Unfortunately I'm stranded at the airport as my flight was cancelled due to major mechanical issues, so I'm writing this from my phone and don't have access to my original example code, but I am monitoring this post so if what I suggested isn't feasible for you to try due to time or expertise just let me know and I'll see what I can determine when I'm back and have time to dig into things a bit. If you are able to get this working for Win7, etc, please let me know as I'd definitely be interested in that for my environment, too.
One last note - one of the other guys from Konference (Ed, I mean you) said the same results could probably be done more easily with powershell, so that may be another option for you.
Regardless, please let me know how it turns out!
John
Ps I just recalled that the printer scripts I have posted are the reworked ones from billprew on ExpertsExchange. These are honestly over my head, but I do have my original versions without the cleanup and merge of new results with other users' old results. These *do* use the writeline method and are more basic. If it would prove helpful, let me know and I'll be happy to post those (just be warned your cleanup methods would be either delete the file on each script run or truncate results (I tried to figure out how to look for the last blank line and remove everything afterward prior to writing the most recent scan, but was unable to get it working).
As far as getting different results when the script runs from the KBOX, this may be due to a permissions error (?) or some part of the command not processing the script correctly. Have you tried the screen resolution script? That one is by far the least involved and the one I started with and got working for the entire process prior to moving on to the others. One other thought - are you running the latest k1000 and agent software?
Hope something there helps. Hopefully someone more guru than I can chime in with something helpful if he/she runs into similar issues. Not that this helps, but everything is working fine in my environment as documented (I copied/pasted directly from my notes and documentation that I keep for myself).
Sorry to hear you're stuck at the airport. I'm not a programmer and my knowledge of vbscript is pretty much non-existent.
I did come across this vbscript that's similar to what you have and does work in win 7.
OutFile = "c:\windows\kbox\myprinters.txt"
Dim fso, of, infile
Set fso = CreateObject("Scripting.FileSystemObject")
Set of = fso.CreateTextFile(OutFile, True)
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery _
("SELECT * FROM Win32_Printer")
Set WshNetwork = WScript.CreateObject("WScript.Network")
of.writeline("This Computer's Name = " & WshNetwork.ComputerName)
For Each objPrinter in colInstalledPrinters
If (objPrinter.Attributes AND 4) = 4 then
of.writeline("*****> Default printer -- Start")
Else
of.writeline("---")
End If
of.writeline("Name: " & objPrinter.Name)
of.writeline("Share name: " & objPrinter.ShareName)
of.writeline("Driver name: " & objPrinter.DriverName)
of.writeline("Caption: " & objPrinter.Caption)
of.writeline("Port: " & objPrinter.PortName)
of.writeline("Location: " & objPrinter.Location)
of.writeline("Description: " & objPrinter.Description)
of.writeline("Server: " & objPrinter.ServerName)
of.writeline("System name: " & objPrinter.SystemName)
of.writeline("Print processor: " & objPrinter.PrintProcessor)
If (objPrinter.Attributes AND 4) = 4 then
of.writeline("*****> Default printer -- End")
Else
of.writeline("---")
End If
Next
of.close
MyVar = MsgBox("Please email myprinters.txt (right click on the file and Send to mail recipient) to mis@gbbragg.com.", 0, "The list of printers has been extracted!")
So... my next question (since I can't play with what you posted at the moment) is - does it give you what you want/need and present it in a message box with an email address link? Looks like that's what it does (besides giving much more printer info than my script, which only gives the name/share name - very cool!). I could definitely rework this into the final version of my script, but I'll need to seek assistance with getting things working as far as cleanup is concerned. Unless someone beats me to it (and anyone is more than welcome), I'll try integrating this into my final code and test on my Win7 PC in the office (I'm still setting it up, but should be fine for this purpose). Once I get that working, I'll see if billprew on ExpertsExchange might be willing/able to rework it like he did with my last one (i.e. dump the text file contents into a dictionary file, check for the username the script is currently running under, update only that listing, and then write it all to the text file). I'll keep you posted and in the meantime will post my pre-billprew final version of my XP-friendly script in case that might help anyone more adept at scripting than us.
John
I'll look into merging the Win7 script (without the cleanup) and see if I might be able to get it working with BillPrew's version (and if not, will see if he might be able to assist). I have a backlog at work, so I'll get to this as soon as I have time.
Thanks for your patience!
John
________________________
Dim objFSO, newfolder
Dim strComputer, objWMIService
Dim fso, fsHandle, objShell,LogFileName, colItems, objItem
Const ForReading = 1
Const ForWriting = 2
i = 1
set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists("c:\Windows\KBOX") Then
newfolder = objFSO.CreateFolder ("c:\Windows\KBOX")
End If
If Not objFSO.FileExists("c:\Windows\KBOX\printers_list.txt") Then
On Error Resume Next
Else
Set objTextFile = objFSO.OpenTextFile _
("C:\Windows\KBOX\printers_list.txt", ForReading)
objTextFile.ReadAll
If objTextFile.Line > 40 Then
Set objFile = objFSO.OpenTextFile("C:\Windows\KBOX\printers_list.txt", ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If i > 15 Then
strContents = strContents & strLine & vbCrLf
End If
i = i + 1
Loop
objFile.Close
Set objFile = objFSO.OpenTextFile("C:\Windows\KBOX\printers_list.txt", ForWriting)
objFile.Write strContents
objFile.Close
Else
End If
End If
Set objShell = CreateObject("Wscript.Shell")
Set fso = Wscript.CreateObject("Scripting.FilesystemObject")
LogFileName= "C:\Windows\KBOX\printers_list.txt"
set fsHandle = fso.OpenTextFile (LogFileName,8,True)
sUser = ConsoleUser(".") ' use "." for local computer
Function ConsoleUser(sHost)
' Returns name of user logged on to console
' If no users are logged on, returns ""
Dim oWMI, colProc, oProcess, sUser, sDomain
Set oWmi = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate,(debug)}!\\" _
& sHost & "\root\cimv2")
Set colProc = oWmi.ExecQuery("Select Name from Win32_Process" _
& " Where Name='explorer.exe' and SessionID=0")
ConsoleUser = ""
For Each oProcess In colProc
lRet = oProcess.GetOwner(sUser, sDomain)
If lRet = 0 Then
ConsoleUser = sUser
End If
Next
End Function
fsHandle.Writeline Now & " - " _
& "Logged in user: " & suser _
fsHandle.Writeline "------------------------------------------------------"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer")
For Each objPrinter in colInstalledPrinters
fsHandle.Writeline objPrinter.name _
Next
fsHandle.Writeblanklines 1
fsHandle.close
set objShell = Nothing
set fso = Nothing
Set objFSO = Nothing
Set objTextFile = Nothing
I played with this a bit tonight at home, both with my old version of the script and billprew's version. After digging around a bit, here's my findings:
1) VBS scripts in Windows 7 that write to protected folders (like C:\Windows, C:\Program Files, etc) will not be able to create the specified folders when run from the user account. In other words, my scripts won't work under Windows 7 as written, but there are a couple of options:
* change the output path to an unprotected folder path (i.e. C:\KBOX)
* manually open an Administrator Command Prompt and run the script
- right-click on Command Prompt -> Run as administrator -> path to script -> type script name -> Enter
** I'm not able to test this at the moment as my K1100 is at the office, but I'm curious if the "run as administrator" option might work
*** I'd personally prefer "hiding" the folder somewhat under C:\Windows and not put it directly on the root, but that may just be me
2) With the adjustments done in 1), my scripts output results to text files successfully. The revised printer scripts with cleanup for shared/multi-profile computers (done by billprew) result in empty text files. I haven't dug into this one yet, but will update with findings as soon as I do.
For the time being, I'm posting another version of my "original" printers list script. This one should be fine for all cases except shared/multi-profile computers. It is set to write to C:\KBOX and will delete any existing printers_list.txt file on each execution. In other words, you should be able to use this now for your Windows 7 PCs. If you'd rather wait until I have solutions for 1) writing the text file to C:\Windows\KBOX and 2) getting billprew's script to write data to the text file, that's fine, too. ^_^
If you want to use the other scripts listed above (screen resolution, etc), just change the output path accordingly (i.e. C:\Windows\KBOX -> C:\KBOX) and you should be good to go.
Thanks for your patience!
John
_____________________________
Dim objFSO, newfolder
Dim strComputer, objWMIService
Dim fso, fsHandle, objShell,LogFileName, colItems, objItem
set objFSO=CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists("C:\KBOX") Then
newfolder = objFSO.CreateFolder ("C:\KBOX")
End If
Set objShell = CreateObject("Wscript.Shell")
Set fso = Wscript.CreateObject("Scripting.FilesystemObject")
If objFSO.FileExists("C:\KBOX\printers_list.txt") Then
fso.DeleteFile "C:\KBOX\printers_list.txt", True
End If
LogFileName= "C:\KBOX\printers_list.txt"
set fsHandle = fso.OpenTextFile (LogFileName,8,True)
sUser = ConsoleUser(".") ' use "." for local computer
Function ConsoleUser(sHost)
' Returns name of user logged on to console
' If no users are logged on, returns ""
Dim oWMI, colProc, oProcess, sUser, sDomain
Set oWmi = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate,(debug)}!\\" _
& sHost & "\root\cimv2")
Set colProc = oWmi.ExecQuery("Select Name from Win32_Process" _
& " Where Name='explorer.exe' and SessionID=0")
ConsoleUser = ""
For Each oProcess In colProc
lRet = oProcess.GetOwner(sUser, sDomain)
If lRet = 0 Then
ConsoleUser = sUser
End If
Next
End Function
fsHandle.Writeline Now & " - " _
& "Logged in user: " & suser _
fsHandle.Writeline "------------------------------------------------------"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer")
For Each objPrinter in colInstalledPrinters
fsHandle.Writeline objPrinter.name _
Next
fsHandle.Writeblanklines 1
fsHandle.close
set objShell = Nothing
set fso = Nothing
Thanks again to billprew from ExpertsExchange who got things working with a different method for pulling the username (the point at which the script was breaking, for some reason). I played with it for a while on my own, but since I previously didn't have a good method for telling where a script was breaking without an error message (which this didn't have), I wasn't having much luck. Another user gave me a good tip (for anyone interested - add "MsgBox GetUser(".")" above the line for "GetPrinters(GetUser("."))" and you'll see the previous script wasn't having much luck with GetUser), so I've added this to my toolbox and can hopefully troubleshoot this situation better in the future. I learn something new everyday. ^_^
Thanks for your patience and hope this helps!
John
_________________________________________________________________________________
_________________________________________________________________________________
printers_list.vbs (note - this is the updated Win7-friendly version reworked by billprew of Experts-Exchange)
_________________________________________________________________________________
' Script reads a current log file of users and printers, elliminates dupes,
' adds in the current user and their printers, and then rewrites the log file.
'
' This script uses a dictionary object to store the printers for each user.
' There will be one dictionary item per user, and then the "data" of that
' user's dictionary item will have the format:
'
' date-string|printer 1|printer 2|printer 3|...|
' Require variables to be defined before usage
Option Explicit
' Define constants
Const ForReading = 1
Const ForWriting = 2
' Define variable used in mainline of script
Dim strBaseDir, strListFile, objFSO, dicUsers, objShell
' Define base folder and log file name
strBaseDir = "C:\KBOX\"
strListFile = strBaseDir & "printers_list.txt"
' Create needed objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject( "WScript.Shell" )
Set dicUsers = CreateObject("Scripting.Dictionary")
' Create the base folder if it doesn't exist
If Not objFSO.FolderExists(strBaseDir) Then
objFSO.CreateFolder(strBaseDir)
End If
' If we have a prior log file, load the users and printers from it first
If objFSO.FileExists(strListFile) Then
GetHistory(strListFile)
End If
' Add printers for the current user to the dictionary
GetPrinters(GetUser("."))
' Dump the contents of the dictionary to the log file
WriteLog(strListFile)
' Subroutnie to load prior history, elliminate any duplicates
Sub GetHistory(strFile)
Dim objFile, strUser, strLine, arrTemp
' Open the log file for reading
Set objFile = objFSO.OpenTextFile(strFile, ForReading)
strUser = ""
' Read each line, looking for user or printer lines, skip blank and dash lines
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If strLine <> "" And Mid(strLine, 1, 10) <> "----------" Then
If Instr(strLine, "Logged in user:") Then
arrTemp = Split(Replace(strLine, " ", " "), " ")
strUser = LCase(arrTemp(7))
' Try to add this user to the dictionary
AddUser strUser, arrTemp(0) & " " & arrTemp(1) & " " & arrTemp(2)
Else
If strUser <> "" Then
' Try to add this printer to the dictionary
AddPrinter strUser, strLine
End If
End If
End If
Loop
objFile.Close
Set objFile = Nothing
End Sub
' Subroutine to get all pronters for this user and add to dictionary
Sub GetPrinters(strUser)
Dim strComputer, objWMI, colPrinters, objPrinter
' Make sure we have a user
If strUser <> "" Then
' Add this user to the dictionary if needed
AddUser strUser, FormatDateTime(Now)
' Identify all printers for this user
strComputer = "."
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colPrinters = objWMI.ExecQuery("Select * from Win32_Printer")
For Each objPrinter in colPrinters
' Try to add each printer to dictionary
AddPrinter strUser, objPrinter.Name
Next
Set colPrinters = Nothing
Set objWMI = Nothing
End If
End Sub
' Subroutine to dump the accumulated data from the dictionary to the log file
Sub WriteLog(strFile)
Dim objFile, strUser, arrData, i
' Open the log file for writing
Set objFile = objFSO.OpenTextFile (strFile, ForWriting, True)
' Process each user in the dictionary
For Each strUser in dicUsers
arrData = Split(dicUsers.Item(strUser), "|")
' Header lines for a user
objFile.Writeline arrData(0) & " - " & "Logged in user: " & strUser
objFile.Writeline "------------------------------------------------------"
' Loop through all printers for this user and write to log file
If UBound(arrData) > 0 Then
For i = 1 to UBound(arrData)-1
objFile.Writeline arrData(i)
Next
End If
objFile.WriteBlankLines 1
Next
objFile.Close
Set objFile = Nothing
End Sub
' Function to get the current user id
Function GetUser(strHost)
GetUser = LCase(objShell.ExpandEnvironmentStrings("%UserName%"))
End Function
' Subroutine to add a user to the dictionary (if it doesn't already exist)
Sub AddUser(strUser, strDate)
If dicUsers.Exists(strUser) Then
dicUsers.Item(strUser) = strDate & "|"
Else
dicUsers.Add strUser, strDate & "|"
End If
End Sub
' Subroutine to add a printer to the dictionary for a user (if it doesn't already exist)
Sub AddPrinter(strUser, strPrinter)
Dim strTemp
strTemp = dicUsers.Item(strUser)
If Instr(strTemp, "|" & strPrinter & "|") = 0 Then
dicUsers.Item(strUser) = strTemp & strPrinter & "|"
End If
End Sub
_________________________________________________________________________________
_________________________________________________________________________________
printer_default.vbs (note - this is my reworking of billprew's Win7-friendly script so that it captures the default printer)
_________________________________________________________________________________
' Script reads a current log file of users and printers, elliminates dupes,
' adds in the current user and their printers, and then rewrites the log file.
'
' This script uses a dictionary object to store the printers for each user.
' There will be one dictionary item per user, and then the "data" of that
' user's dictionary item will have the format:
'
' date-string|printer 1|printer 2|printer 3|...|
' Require variables to be defined before usage
Option Explicit
' Define constants
Const ForReading = 1
Const ForWriting = 2
' Define variable used in mainline of script
Dim strBaseDir, strListFile, objFSO, dicUsers, objShell
' Define base folder and log file name
strBaseDir = "C:\KBOX\"
strListFile = strBaseDir & "printers_default.txt"
' Create needed objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject( "WScript.Shell" )
Set dicUsers = CreateObject("Scripting.Dictionary")
' Create the base folder if it doesn't exist
If Not objFSO.FolderExists(strBaseDir) Then
objFSO.CreateFolder(strBaseDir)
End If
' If we have a prior log file, load the users and printers from it first
If objFSO.FileExists(strListFile) Then
GetHistory(strListFile)
End If
' Add printers for the current user to the dictionary
GetPrinters(GetUser("."))
' Dump the contents of the dictionary to the log file
WriteLog(strListFile)
' Subroutnie to load prior history, elliminate any duplicates
Sub GetHistory(strFile)
Dim objFile, strUser, strLine, arrTemp
' Open the log file for reading
Set objFile = objFSO.OpenTextFile(strFile, ForReading)
strUser = ""
' Read each line, looking for user or printer lines, skip blank and dash lines
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If strLine <> "" And Mid(strLine, 1, 10) <> "----------" Then
If Instr(strLine, "Logged in user:") Then
arrTemp = Split(Replace(strLine, " ", " "), " ")
strUser = LCase(arrTemp(7))
' Try to add this user to the dictionary
AddUser strUser, arrTemp(0) & " " & arrTemp(1) & " " & arrTemp(2)
Else
If strUser <> "" Then
' Try to add this printer to the dictionary
AddPrinter strUser, strLine
End If
End If
End If
Loop
objFile.Close
Set objFile = Nothing
End Sub
' Subroutine to get default pronter for this user and add to dictionary
Sub GetPrinters(strUser)
Dim strComputer, objWMI, colPrinters, objPrinter
' Make sure we have a user
If strUser <> "" Then
' Add this user to the dictionary if needed
AddUser strUser, FormatDateTime(Now)
' Identify default printer for this user
strComputer = "."
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colPrinters = objWMI.ExecQuery("Select * from Win32_Printer where Default = 'True'")
For Each objPrinter in colPrinters
' Try to add each printer to dictionary
AddPrinter strUser, objPrinter.Name
Next
Set colPrinters = Nothing
Set objWMI = Nothing
End If
End Sub
' Subroutine to dump the accumulated data from the dictionary to the log file
Sub WriteLog(strFile)
Dim objFile, strUser, arrData, i
' Open the log file for writing
Set objFile = objFSO.OpenTextFile (strFile, ForWriting, True)
' Process each user in the dictionary
For Each strUser in dicUsers
arrData = Split(dicUsers.Item(strUser), "|")
' Header lines for a user
objFile.Writeline arrData(0) & " - " & "Logged in user: " & strUser
objFile.Writeline "------------------------------------------------------"
' Loop through all printers for this user and write to log file
If UBound(arrData) > 0 Then
For i = 1 to UBound(arrData)-1
objFile.Writeline arrData(i)
Next
End If
objFile.WriteBlankLines 1
Next
objFile.Close
Set objFile = Nothing
End Sub
' Function to get the current user id
Function GetUser(strHost)
GetUser = LCase(objShell.ExpandEnvironmentStrings("%UserName%"))
End Function
' Subroutine to add a user to the dictionary (if it doesn't already exist)
Sub AddUser(strUser, strDate)
If dicUsers.Exists(strUser) Then
dicUsers.Item(strUser) = strDate & "|"
Else
dicUsers.Add strUser, strDate & "|"
End If
End Sub
' Subroutine to add a printer to the dictionary for a user (if it doesn't already exist)
Sub AddPrinter(strUser, strPrinter)
Dim strTemp
strTemp = dicUsers.Item(strUser)
If Instr(strTemp, "|" & strPrinter & "|") = 0 Then
dicUsers.Item(strUser) = strTemp & strPrinter & "|"
End If
End Sub
_________________________________________________________________________________
_________________________________________________________________________________
In regards to the local & network drives script, I checked my setup on the K1000 and don't have anything special there. Are you running this:
1) as an Online KScript
2) with "Run As User logged into the console" for the Run As section?
If you run it as an Offline KScript or with something different in the Run As section, it will only show the local drives.
Hope that helps!
John
Original script result:
Screen Resolution:1280 * 960
[string]
Result with trailing carriage returns removed:
Screen Resolution:1600 * 1200 [string]
Server version is 5.3.47927, agent version is 5.3.49657.
Custom inventory rule is entered as:
ShellCommandTextReturn(cmd /c type C:\temp\KBOX\screen_resolution.txt)
Am I missing something or should it go to KACE support?
You have everything set correctly and per my one slide, the text files aren't being displayed correctly in the K1000 Inventory and Reporting screens (for me, it was putting </br> after each line instead of doing an actual line break). One of the KACE engineers was kind enough to tweak the way the Inventory read the text files so things look as they should on my K1000. But it's probable the issue is still there for everyone else's, at least until the next version release which should have the fix the engineer did on mine. I'll drop him a line and see what he says, but (in my mind) the main thing is that the data is there for reference purposes. For what it's worth, I didn't run into these text file formatting issues when I initially set this up on version 5.1.
Thanks,
John
I double-checked the Custom Inventory Rule, and what I have is:
ShellCommandTextReturn(type c:\windows\kbox\script_output_file.txt)
So maybe try this for yours and see if it changes anything:
ShellCommandTextReturn(type C:\temp\KBOX\screen_resolution.txt)
Also, I checked my versions and my server is 5.3.45497 and agents are 5.3.47173.
John
Sorry for the scattered comments - I've been out of the office for 4 days, trying to play catch-up and also spaced out from bronchitis.... fun stuff.
I just re-read your post and saw the resolution sizes jumped. When you run the script from the K1000, is it putting the "1600 * 1200" in the text file that's output to your C:\Temp\KBOX folder? Do you have multple monitors (or a laptop with an external monitor) with one using this resolution?
The ShellCommandTextReturn command just grabs what's in the text file, so the numbers shouldn't be changing (i.e. shouldn't be a K1000-related issue).
John
Both are dumping the results into the temp directory, as I know that it has the needed security rights for all users on WinXP through Win7.
I was using the "cmd /c" syntax as that was what you had listed in the text portion of your first post and due to the discussion going on here: http://itninja.com/question/outlook-profile065
Using ShellCommandTextReturn(type C:\temp\KBOX\screen_resolution.txt) returns nothing, and removes it from inventory.
I checked my K1000 to see exactly what I'm using and it's this:
ShellCommandTextReturn(cmd /c type C:\WINDOWS\KBOX\screen_resolution.txt)
Just for the record, what I listed a few minutes ago is what I had used under 5.1 - I forgot about my support call to get the correct syntax for 5.3 (which corresponds to the post you referenced).
As for the final formatting in the Inventory screen, yes, I would take that up with support at this point. Just FYI, they may already have a similar bug report on it since I did report it earlier.
John
One of the Kace engineers did a tweak to get rid of the <br/> being listed in the Inventory - Computers screen, and I'm pretty sure he committed it to 5.4 so that should be fixed for everyone when it gets released.
As for the reports, I did a simple CSV report and cleaned things up for the presentation and made note of the bug.
If it's of any interest to you, I also submitted the following bug report (which was sent over to the K1 PM), which makes mention of the above issues as well as similar issues in the KB part of the K1000. Not sure how everything will appear here in the forum, since I've noticed AppDeploy appears to have its own formatting issues.
Hope that helps clarify things a bit.
John
_____________________________________________________________ Issue: Line breaks (carriage returns) not being recognized/formatted correctly in KBOX1100, appears to be pervasive throughout system _____________________________________________________________ Examples: 1) Inventory - Computer - Custom Fields when import text with multiple lines via ShellCommandTextReturn * note - Kace engineer fixed this on my KBOX and I believe committed the code to the 5.4 release _____________________________________________________________ 2) Reports - when pulling from Custom Fields section of Inventory that imported text with multiple lines Example: AFOX 192.168.205.19 10/28/2011 12:04:51 PM - Logged in user: afox<br/>------------------------------------------------------<br/>Microsoft Office Document Image Writer<br/>HP LaserJet 1100 (MS)<br/>\\srv-mln01\mln155<br/><br/>10/7/2011 8:02:57 AM - Logged in user: AFOX<br/>------------------------------------------------------<br/>Microsoft Office Document Image Writer<br/>HP LaserJet 1100 (MS)<br/>\\srv-mln01\mln155<br/><br/> _____________________________________________________________ This is how it should look (and how it does look in the Computer Inventory listing following Kace engineer's fix): 4) * Printers List: 10/28/2011 12:04:51 PM - Logged in user: afox
------------------------------------------------------
Microsoft Office Document Image Writer
HP LaserJet 1100 (MS)
\\mln-server\mln155
10/7/2011 8:02:57 AM - Logged in user: AFOX
------------------------------------------------------
Microsoft Office Document Image Writer
HP LaserJet 1100 (MS)
\\mln-server\mln155
_____________________________________________________________ 3) Helpdesk - Knowledgebase - whenever creating article with multiple lines, the first carriage return is ignored, however multiple carriage returns are processed correctly. Have to *add* "<br/> to each line in order for text to appear correctly in KB articles. (Not sure if this is the same issue as 1 & 2, but since it's related to <br/> I'm including it. Also, I tried "double returns" for each line, but strangely these were processed correctly. This is as it appears when manually typed (or imported from a Helpdesk ticket) into a new KB article (prior to save in KB): *Stopped & restarted Print Spooler and TCP/IP Print Server services on PGH-PRINT. Ran following commands in QAD: disable strs3
(wait a few seconds)
enable strs3
cd /u00/strs/scripts
./stream.sh stop
(wait a few seconds)
./stream.sh start
Exit _____________________________________________________________ This is how it appears in KB after saving without <br/> added to each line (note multiple line breaks processed correctly): *Stopped & restarted Print Spooler and TCP/IP Print Server services on PGH-PRINT. Ran following commands in QAD: disable strs3 (wait a few seconds) enable strs3 cd /u00/strs/scripts ./stream.sh stop (wait a few seconds) ./stream.sh start exit _____________________________________________________________ This is the necessary format (with <br/> added to each line to get it to appear correctly in KB (post save): *Stopped & restarted Print Spooler and TCP/IP Print Server services on PGH-PRINT.<br/> Ran following commands in QAD:<br/> disable strs3<br/> (wait a few seconds)<br/> enable strs3<br/> cd /u00/strs/scripts<br/> ./stream.sh stop<br/> (wait a few seconds)<br/> ./stream.sh start<br/> Exit _____________________________________________________________ This is how it appears in KB after saving with two returns at the end of each line (each one processed correctly): *Stopped & restarted Print Spooler and TCP/IP Print Server services on PGH-PRINT. Ran following commands in QAD: disable strs3 (wait a few seconds) enable strs3 cd /u00/strs/scripts ./stream.sh stop (wait a few seconds) ./stream.sh start _____________________________________________________________
John, great work. I have taken one of your scripts and modified it to get the installed security software on the machine and what state it is in. I tried to use some of your memory stick to convert the productstate to useful words but couldn't get it to work (State codes http://blog.crayon.no/blogs/janegil/archive/2011/06/12/use_2D00_windows_2D00_powershell_2D00_to_2D00_get_2D00_antivirus_2D00_product_2D00_information.aspx). I have tested the script by just runnning it locally and it creates the txt file fine, when I loaded it into Kace using your suggested settings as an Offline or Online script it fails when run not sure why. Not sure if anyone here is a bit better with VB to make the nameing part work.
Dan
'Script Start Dim objFSO, newfolder Dim strComputer, objWMIService Dim fso, fsHandle, objShell,LogFileName, colItems, objItem set objFSO=CreateObject("Scripting.FileSystemObject") If Not objFSO.FolderExists("c:\Windows\KBOX") Then newfolder = objFSO.CreateFolder ("c:\Windows\KBOX") End If Set objShell = CreateObject("Wscript.Shell") Set fso = Wscript.CreateObject("Scripting.FilesystemObject") If objFSO.FileExists("c:\Windows\KBOX\security_software.txt") Then fso.DeleteFile "c:\windows\KBOX\security_software.txt", True End If LogFileName= "C:\Windows\KBOX\security_software.txt" set fsHandle = fso.OpenTextFile (LogFileName,8,True) fsHandle.Writeline "------------------------------------------------------" fsHandle.Writeline Now fsHandle.Writeline "------------------------------------------------------" strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\SecurityCenter2") Set colItems = objWMIService.ExecQuery _ ("Select * from AntiVirusProduct") For Each objItem in colItems fsHandle.Writeline "Name: " & objItem.displayName fsHandle.Writeline "Status: " & objItem.productstate fsHandle.Writeline "------------------------------------------------------" NEXT fsHandle.Writeblanklines 1 fsHandle.close set objShell = Nothing set fso = Nothing 'Script End
Comments:
-
Dan,
I noticed your script is set to output the text file to C:\Windows\KBOX. If you are running this on Win7, it won't work due to this being a protected folder. I have revised the scripts since the original post and have a blog with these updates - please review and let me know if you still need any assistance:
http://www.itninja.com/blog/view/inventorying-reporting-on-user-profile-specific-other-non-inventoried-data
John - jverbosk 12 years ago
so that the conversation will remain readable.