/build/static/layout/Breadcrumb_cap_w.png

Extending the Computer Inventory to Support User Profile Specific & Other Non-Inventoried Data

Supporting notes & examples for Kace Konference 2011 presentation:
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:


0 Comments   [ + ] Show comments

Answers (40)

Posted by: jverbosk 12 years ago
Red Belt
1
Slide 1


Posted by: jverbosk 12 years ago
Red Belt
1

Workaround for Line Break Character Bug in Reports Generated on Inventory Custom Fields

http://itninja.com/blog/view/workaround-for-line-break-character-bug-in-reports-generated-on-inventory-custom-fields

John

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 2

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 3

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 4

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 5

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 6

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 7

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 8

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 9

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 10

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 11

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 12

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 13

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 14

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 15

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 16

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 17

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 18

Posted by: jverbosk 12 years ago
Red Belt
0
Slide 19



Posted by: jverbosk 12 years ago
Red Belt
0
Slide 20

Posted by: jverbosk 12 years ago
Red Belt
0
That's all of it. Any corrections or suggestions, please let me know. Hope this helps somebody out there. ^_^

John
Posted by: GillySpy 12 years ago
7th Degree Black Belt
0
This is great stuff. This is the kind of thing that I was hoping customer's would start doing. A slightly simpler example that shows the thought process is in faq 968

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.
Posted by: londeaux 12 years ago
Second Degree Green Belt
0
Hey John,

I tried the printers list and default printer vbscript and I get exported is a blank text file.

Also if I run the vbscript from KACE it doesn't report the mapped network drives, just local drives. If I run the vbscript from the PC, it'll show the mapped network drives.
Posted by: jverbosk 12 years ago
Red Belt
0
Londeaux,

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).
Posted by: londeaux 12 years ago
Second Degree Green Belt
0
Hey,

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.

Dim OutFile
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!")
Posted by: jverbosk 12 years ago
Red Belt
0
Very cool! And don't feel alone, I'd never done any vbs programming prior to getting my kboxes. I just figured it would be the most straightforward way of getting what I wanted/needed in the Inventory listings since nothing in the KBs or documentation dealt with this stuff directly and I really wanted to dump my old inventory system so I could have integrated data (a one-stop shop instead of bouncing between consoles all the time). The most I'd ever done with programming was just read a couple of C++ books for fun so I could at last understand he principles. My stuff is much more akin to command line batch files, nothing that sophisticated.

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
Posted by: jverbosk 12 years ago
Red Belt
0
Here's my original printers list script. It's set to remove the first 15 lines when the text file exceeds 40 lines for the cleanup routine, so it doesn't grow forever. Just posting this in case it might be helpful to anyone.

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
Posted by: jverbosk 12 years ago
Red Belt
0
Fun to be back in the office after being out for a week - didn't have time to do anything in the KBOX except enter tickets.... OK, done with the self-pity party. ^_^

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
Posted by: jverbosk 12 years ago
Red Belt
0
OK, I've got Win7 x86 & x64 compatible versions of the printer scripts. As noted in my previous post, these are set to write to C:\KBOX on the client. I still need to test if "running these as administrator" from the K1000 will allow them to write to C:\Windows\KBOX, but for the time being this should get things working for your Win7 clients. These also work for WinXP, so can be used if you have a mixed environment.

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
_________________________________________________________________________________
_________________________________________________________________________________
Posted by: jverbosk 12 years ago
Red Belt
0
londeaux,

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
Posted by: sramsey 12 years ago
Senior Yellow Belt
0
Looking at these, and getting an odd result in the custom inventory fields. All the lists include "[string]" at the end of them. This shows up regardless of blank lines at the end of the text file.

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?
Posted by: jverbosk 12 years ago
Red Belt
0
@sramsey

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
Posted by: jverbosk 12 years ago
Red Belt
0
@sramsey

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
Posted by: jverbosk 12 years ago
Red Belt
0
@sramsey

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
Posted by: sramsey 12 years ago
Senior Yellow Belt
0
Sorry, those are from 2 different machines: one with the original script, one that is not creating the blank lines. I whiffed on that in my original post.

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.
Posted by: jverbosk 12 years ago
Red Belt
0
@sramsey

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
Posted by: AJStevens 12 years ago
Senior Purple Belt
0
Doing something similiar, and I also seem to have an unwanted carriage return and [string] at the end.
When doing reports there's also "<br>" I could do without.

How did you get rid of the carriage return at least?
Posted by: jverbosk 12 years ago
Red Belt
0
This is a bug in 5.3, wasn't there in 5.1 when I initially set it up.

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 _____________________________________________________________
Posted by: danflynn 11 years ago
Orange Belt
0

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 11 years ago
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Don't be a Stranger!

Sign up today to participate, stay informed, earn points and establish a reputation for yourself!

Sign up! or login

Share

 
This website uses cookies. By continuing to use this site and/or clicking the "Accept" button you are providing consent Quest Software and its affiliates do NOT sell the Personal Data you provide to us either when you register on our websites or when you do business with us. For more information about our Privacy Policy and our data protection efforts, please visit GDPR-HQ