/build/static/layout/Breadcrumb_cap_w.png

Blog Posts tagged with K1000 Scripting

Ask a question

Scripting the fix for "Admin Alert! showing during inventory updates" on OS X 10.5 systems with Agent version 5.3.53177

The 5.3.53177 release of the KACE Agent contains a bug that causes the "Agent Alert!" icon to appear in the dock during every inventory update, even though it should only appear when an alert is pushed to the client machine. (See this ITNinja Q for more details: http://www.itninja.com/question/admin-alert-poping-on-apple-systems)

To automatically fix this issue on affected OS X 10.5 systems, I have created a script that will apply the necessary plist fix, so that it doesn't have to be manually changed on each affected system.

 

1) First, create a file named plist_fix.sh containing the following: **(The number highlighted in red must be changed to the script # you create on step 3)**

#!/bin/sh
rm -rf /Library/Application\ Support/Dell/KACE/bin/AdminAlert.app/Contents/info.plist
sleep 10
ditto /Library/Application\ Support/Dell/KACE/data/scripts/87/Info.plist /Library/Application\ Support/Dell/KACE/bin/AdminAlert.app/Contents/
sleep 5
sudo /Library/Application\ Support/Dell/KACE/bin/runkbot 4 0
exit 0

 

2) Next, create a copy of the Info.plist file located in ... with the following additional entries at the bottom of the file:

      <key>LSUIElement</key>
<true/>
<key>plist_fixed</key>
<string>Yes</string>
</dict>
</plist>

3) Finally, create an "Offline KScript" and attach the 2 files created above as dependencies, and add the following Job rules:

Verify

  1. Verify that the plist value LSUIElement in the plist /Library/Application\ Support/Dell/KACE/bin/AdminAlert.app/Contents/info.plist exists.

On Success

  1. Log plist already updated to status.

Remediation

  1. Kill the process AdminAlert.
  2. Launch $(KACE_DEPENDENCY_DIR)\plist_fix.sh with params .

On Remediation Success

  1. Log plist for 10.5 client successfully updated to output.

On Remediation Failure

    1. Log plist not successfully updated!!! to output.
 
 
 
 

The Script can be run as a 'one-time' push to all OS X 10.5 machines, or you can create a Custom Inventory Rule and Smart Label based on the plist_fixed key. You can then schedule the script to run regularly on machines which are labled as not having that plist entry.

 

The Custom Inventory Rule I used to identify machines which have had this fix applied is:

PlistValueExists(/Library/Application Support/Dell/KACE/bin/AdminAlert.app/Contents/info.plist, plist_fixed)

 

I then Created a smart label to identify the applicable (10.5) machines which did not yet have this plist entry (Keep in mind we you may have to change the ORG5 prefix to suit your environment):

 

select *, UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(LAST_SYNC) as LAST_SYNC_TIME,
             UNIX_TIMESTAMP(MACHINE.LAST_SYNC) as LAST_SYNC_SECONDS
     from ORG5.MACHINE
     LEFT JOIN KBSYS.KUID_ORGANIZATION ON KUID_ORGANIZATION.KUID=MACHINE.KUID

     LEFT JOIN KBSYS.SMMP_CONNECTION ON SMMP_CONNECTION.KUID = MACHINE.KUID

             AND KUID_ORGANIZATION.ORGANIZATION_ID = 5
     where ((((  MACHINE.CLIENT_VERSION like '%5.3.53177%')

      AND OS_VERSION like '%10.5%')

      AND (1 not in (select 1 from ORG5.SOFTWARE, ORG5.MACHINE_SOFTWARE_JT

        where MACHINE.ID = MACHINE_SOFTWARE_JT.MACHINE_ID

          and MACHINE_SOFTWARE_JT.SOFTWARE_ID = SOFTWARE.ID

          and SOFTWARE.DISPLAY_NAME = 'Fixed plist for 10.5 Machines running agent 5.3.53177')) ))

 

With this combination of Custom Inventory Rule, Smart Label, and Script, you never need worry that someone is seeing this bug on their system, as it will automatically apply this fix at the interval you specify in the script!

View comments (1)

KACE: Microsoft App-V integration scripts for the K1000 now available!

Wanted to let everyone know about some scripts that are now available for the K1000 that you’ll find of interest if you are using, or considering using Microsoft App-V for application virtualization.  Best of all, you can download them here, now and at no cost!

These scripts allow you to manage Microsoft App-V sequencing and deployment directly from your K1000 console in the same manner you deploy all traditionally installed software applications.  To be clear, it does not replace any Microsoft App-V licensing or software (you still need to be compliant and have the software installed on each machine), but this does allow you send software images from either a DVD or network share to the MS sequencer and deploy that sequenced image to your client machines directly from the K1000 interface.  In addition, K1000 inventory will include all App-V installed applications from each machine, right next to all of your traditionally installed software applications. So if you are a K1000 customer that wants an easy way to sequence, deploy and track App-V applications, these scripts are for you!


You can download these scripts and a User Guide for setup HERE.  The guide will walk you through importing and setting up / executing the scripts to help manage your App-V environment!

 

For more information on Microsoft App-V and whether it might be a good fit for your organization, visit Microsoft's App-V home page.

 

We hope you find these scripts helpful!  Let us know what you think!

View comments (1)

Inventorying & Reporting on User Profile-Specific & Other Non-Inventoried Data

In a nutshell - if you can output data to a text file, this method will allow you to get it into the Inventory - Custom Fields section of your K1000.  On my network I use it to collect network drive & printer info, screen resolution and other things the K1000 doesn't support natively.

I've referenced this post a few times since ITNinja went live, and just today realized that a number of things didn't migrate smoothly (particularly in the example scripts section...).  Therefore, as I feel this info is still relevant, I'm doing a clean-up, update and quasi-repost, which will hopefully make this more usable than the original version.  I've also made a few revisions so that things should work with *both* WinXP and Win7 - when I originally did all of this I didn't have any Win7 machines using all of this and have since changed a few things.

There are a number of good comments in the original post, so for anyone interested, here's the link:

Extending the Computer Inventory to Support User Profile Specific & Other Non-Inventoried Data
http://www.itninja.com/question/extending-the-computer-inventory-to-support-user-profile-specific-other-non-inventoried-data

Also, for anyone planning on reporting on the data collected using this method, you'll probably find this post useful:

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

As usual, hope this helps somebody!

John
_________________________________________________________________________________

***Notes***

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.

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.

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 (by default).  See the link above for a post on how to address this with some tweaking of the report code.
_________________________________________________________________________________
_________________________________________________________________________________

Custom Inventory Items & Reporting for Scripts

1) Create a custom folder on all PCs for holding script output files (i.e. C:\KBOX)
    - this can be done using a vbs script and run from KBOX
    - avoid creating in protected folders in Win7 (i.e. C:\Windows\KBOX) as the scripts may not work

2) Create a vbs script that outputs to a text file to a custom folder (i.e. C:\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
    
   See this post:
   http://itninja.com/blog/view/workaround-for-line-break-character-bug-in-reports-generated-on-inventory-custom-fields

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        
       1) Always Fail
     On Success    
        <nothing>
     Remediation
       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:\KBOX)
          File          name of output file (i.e. screen_resolution.txt)

     On Remediation Success
       1) Log message
          successfully ran screen_resolution script

     On Remediation Failure
       1) Log message
          failed to run screen_resolution script

8) Save
_________________________________________________________________________________
_________________________________________________________________________________

Example scripts and output
_________________________________________________________________________________

1) local_and_network_drives.vbs

4/13/2012 8:03:51 AM - Logged in user:  jsmith
------------------------------------------------------
C: Local Hard Drive
D: CD/DVD Drive
G: \\siteserver\data
H: \\fileserver\helpdesk
I: \\siteserver\users\sfrazier
L: \\siteserver\public
M: \\fileserver\manufacturing
P: \\fileserver\public
Q: \\fileserver\QA
R: \\fileserver\Research
S: \\fileserver\Sales&Marketing

_________________________________________________________________________________

2) memory_info.vbs

------------------------------------------------------
4/13/2012 8:03:18 AM
------------------------------------------------------
Slots:                2
Maximum Capacity:     4096 MB
------------------------------------------------------
Memory Stick:         DIMM_1
Capacity:             512 MB
Form Factor:          DIMM
Memory Type:          TQFP
Speed:                333 MHz
Data Width:           64
------------------------------------------------------
Memory Stick:         DIMM_2
Capacity:             512 MB
Form Factor:          DIMM
Memory Type:          TQFP
Speed:                333 MHz
Data Width:           64
------------------------------------------------------

_________________________________________________________________________________

3) printer_default.vbs

4/13/2012 4:05:21 AM - Logged in user:  jsmith
------------------------------------------------------
HP LaserJet P2035n (Landscape - NWA)

4/11/2012 12:04:25 PM - Logged in user:  jdoe
------------------------------------------------------
\\srv-ec01\LANIER LD325

_________________________________________________________________________________

4) printers_list.vbs

4/13/2012 8:04:00 AM - Logged in user:  jsmith
------------------------------------------------------
Microsoft Office Document Image Writer
HP LaserJet P2035n (Landscape - NWA)
HP LaserJet P2035n
HP LaserJet 2100 PCL6
\\srv-ec01\ec156

4/11/2012 12:04:47 PM - Logged in user:  jdoe
------------------------------------------------------
Microsoft Office Document Image Writer
HP LaserJet P2035n (Landscape - NWA)
HP LaserJet P2035n
HP LaserJet 2100 PCL6
\\srv-ec01\HP LaserJet 2100 Series PCL 6
\\srv-ec01\LANIER LD325

_________________________________________________________________________________

5) screen_resolution.vbs

1024 * 768

_________________________________________________________________________________
_________________________________________________________________________________

Scripts (compatible with WinXP & Win7)
_________________________________________________________________________________

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:\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\local_and_network_drives.txt") Then
fso.DeleteFile "c:\KBOX\local_and_network_drives.txt", True
End If

LogFileName= "C:\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:\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\memory_info.txt") Then
fso.DeleteFile "c:\KBOX\memory_info.txt", True
End If

LogFileName= "C:\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
_________________________________________________________________________________
_________________________________________________________________________________

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 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 & "printer_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 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 (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
_________________________________________________________________________________
_________________________________________________________________________________

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, 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
_________________________________________________________________________________
_________________________________________________________________________________

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:\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\screen_resolution.txt") Then
fso.DeleteFile "c:\KBOX\screen_resolution.txt", True
End If

LogFileName= "C:\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
_________________________________________________________________________________

View comments (5)

How to resolve a corrupt installed Mac Application through the K1000

Situation:

An application was patched or update while launched causing it to be damaged and resulting in the spinning beachball during launch or use.

Resolution:

There are a couple of ways that can fix this type of problem. Deciding which method to use would depend upon how wide spread the issue is and the complexity of your environment. Below are two concepts that can be used in resolving this type of problem. The first method covers the use of a shell script to stop the application process, removing it from the agent, followed by deploying and installing a known good version of the application.  With the help of a custom inventory rule and a smart machine label, the first resolution will detect other Mac agents exhibiting the same issue and run the shell script only one time to eliminate the conflict. 

The second resolution takes the process a step further by using a Plist to also provide preventative maintenance in case the issue returns after it has been resolved. The custom Plist will simply create a placeholder with no stamp inside. The file itself will still carry a standard system stamp. This is similar to what you would do with a custom registry key in a Windows environment.

The example below covers the use of an example shell script, custom inventory rule and smart machine label to resolve this type of problem (using Firefox as an example):

  1. Navigate to Scripting>choose action>add new item. Choose Online Shell Script as the script type.
  2. Upload the application used in the managed install as a dependancy.
  3. Write a script that will kill the application service, uninstall the application and then reinstall the application, followed by tagging a note when the job is complete.  Below is a sample shell script for Firefox:


  4. Save the script. Stay in Scripting. Put your cursor over the newly created script and view the identification number created for it at the bottom left of your web browser.




  5. Launch the script and edit the shell script by putting the ID number in place of the 'XXX' listed in the above example. Save.
  6. Navigate to Inventory>Software>Add New Item. Give it a title and create the Custom Inventory Rule to search for the note added to the bottom of the shell script.




  7. Save.
  8. Select Home>Label>Smart Labels>Choose Action>Add New item. Select Add New Machine Smart Label.
  9. Create the Smart Machine Label with the below similar criteria:





    NOTE: In place of 'Firefox 12 Replacement Script' use the title of the Software Item name given to the Custom Inventory Rule.

  10. The above Smart Machine Label is basic and further criteria can be added. Once catered to your liking, save it.
  11. Allow your agents to check in prior to running the script so that the machine label is given ample time to associate to the systems maching the above criteria. Then deploy the script manually or on a schedule.

Below are the steps to create a custom Plist that will be used as a container when resolving this type of issue.

  1. Navigate to Scripting>Choose Action>Add New Item.
  2. Select Script Type as Online Shell Script.
  3. Give the plist script a name. For this example, the name will be "com.kace.kinv.plist".
  4. Create and deploy the Shell Script with the contents listed in the below picture.





    This script will Date/time stamp the .plist.

  5. Save.

The next process is to create a script to uninstall/install the application with the help of the Plist. Stay in Scripting and create a new script. This time, choose Script Type as Online Kscript. Upload the application as the dependancy and use a script similar to the below screenshot using TextWrangler as an example.




To go into the script itself further, below is the breakdown of the script and categories to choose when creating this type of script.





NOTE: The File: field is not required, so leave this blank.





When completed, save the script. Once the Plist and Script have been saved, Create a Machine Smart Label to find machines that do not contain the application. The last step is to create a Custom Inventory Rule to Identify Systems with a plistReturnValue string.




NOTE: The 3142 reference is in reference to the build number of the application used in this example. This is helpful when dealing with an application publisher version that has several build numbers and you are replacing an older build number with a newer of the same version.

View comments (1)

x64 vs x86 : 32bit application redirects

The K1000 5.3.x agent is a 32bit application. When it is installed on a 64bit Windows platform, things it attempts to do can get redirected by the OS. Simple things like trying to read or write to the registry or system32 folder doesn't always function the same as the agent's predecesssors. There are ways to account for/workaround when dealing with these redirects.

This MS KB article will show you similar to the information I’m placing below:
http://support.microsoft.com/kb/942589

On a Windows x64 machine

1) A 32-bit application maps as follows:

    - c:\windows\system32 -> c:\windows\syswow64 (32-bit)
    - c:\windows\syswow64 -> c:\windows\syswow64 (32-bit)
    - c:\windows\sysnative -> c:\windows\system32 (64-bit)

2) A 64-bit application maps as follows:

    - c:\windows\system32 -> c:\windows\system32 (64-bit)
    - c:\windows\syswow64 -> c:\windows\syswow64 (32-bit)
    - c:\windows\sysnative -> not valid

This will also affect registry keys. When needing to write to the actual 64bit registry, you need to call the reg command from sysnative. If you are using a batch that has parameters, the batch will switch back to 32bit redirects due to switches when executed by the agent.

On the registry, the 5.3.X agent has another way of accounting for the 64bit registry. If you aren’t doing the registry commands via a batch or trying to leverage regedit or reg.exe, you can use things like HKLM64 to reference the 64bit hive instead of allowing the agent to get redirected to the 32bit hive which populates the wow6432node locations in the 64bit registry. Leveraging the HKLM64 is very useful in Custom Inventory Rules too.

View comments (1)
Showing 1 - 5 of 62 results

Top Contributors

Talk About Troubleshooting