Display a message on end users computer

Discussion in 'ASDK/SSDK' started by ksweet, Mar 9, 2007.

  1. ksweet New Member

    Will display a message on end users computer...

    The time out is set to 30 seconds and then asks if you want to display the message again, I tried to set it to a higher value (24 hours, 1 hour, 30 mins) but it still times out after less than 1 min (didn't time it to get the exact time)
  2. Mike Altiris Engineer (Super Mod)

    to me this is easily the best post of the year. Good find! Thanks for sharing!
  3. AeXAdmin New Member

    Having a little trouble getting this one going. The script doesn't display any errors, but the popup doesn't appear.

    Any bright ideas about what might be missing?

    Thanks!
  4. ksweet New Member

    If this reg key is set the script will work, show no errors but no message ballon will show on the client PC.





    Remarks

    This method only works if the Microsoft balloon feature is enabled in the registy. See http://support.microsoft.com/default.aspx?scid=kb;en-us;307729 for more information.

    Code:
    REGEDIT4  
     [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]
    "EnableBalloonTips"=dword:00000000
  5. AeXAdmin New Member

    That did the trick, thanks for your help!!
  6. RWChandler1949 New Member

    Message on Computer

    How are you guys sending this out. Can you feed it a list of computer names. I want to send out a "Please Restart Your Computer" type of message to several computers at the same time.
  7. jebba Member


    I'm curious too - is this sent through the DS?
  8. jebba Member

    anyone?
  9. Mike Altiris Engineer (Super Mod)

    ...or a SWDelivery Package/Policy (use 'cscript.exe yourvbs.vbs' in your program). or a task server task against a swd package.
  10. ksweet New Member

    You run this script on one computer to show a message on another computer.

    Since the message is only displayed for 30 seconds I would not use it to alert users to important messages that they need to do something about...

    for that I use this:
    Code:
    Set MyShell = WScript.CreateObject("WScript.Shell")
    MyAnswer = MyShell.Popup("Can you read this message?", 0, "Read Me", vbOKOnly + vbCritical + vbSystemModal)
    
  11. jebba Member

    I guess I'm saying HOW do you run the script? copy into a txt file - batch file??
    thanks
  12. Mike Altiris Engineer (Super Mod)

    Like ksweet was explaining, the way he wrote the script you don't need to run it through anything.

    Try copying the code into notepad and save to somefile.vbs

    double-click it

    tada! Read-up on vbscripting and you can take out the messagebox and run it as part of a DS job or NS task.
  13. Brandon Active Member

    Could someone correct me here. I would like to use this but with an array to message a group of computers. I don't know much vbs though.

    1. Can I modify the object in the loop each time for a new computer?
    2. How can I dynamically initialize an array -- Dim computers(x) ?

    Here is what I have:

    Code:
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]On[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Error[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Resume Next[/COLOR][/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#008000]' 0 = No Icon[/COLOR][/SIZE][/FONT]
    [SIZE=3][FONT=Lucida Console][COLOR=#008000]' 1 = Information Icon[/COLOR][/FONT][/SIZE]
    [SIZE=3][FONT=Lucida Console][COLOR=#008000]' 2 = Warning Icon[/COLOR][/FONT][/SIZE]
    [SIZE=3][FONT=Lucida Console][COLOR=#008000]' 3 = Error Icon[/COLOR][/FONT][/SIZE]
    [SIZE=3][FONT=Lucida Console][COLOR=#008000]' 4 = Altiris[/COLOR][/FONT][/SIZE]
    [FONT=Lucida Console][SIZE=3]MyIcon = 2[/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#008000]' Set you your default message title[/COLOR][/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3]MyTitle = [/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#800000]"Message from IT"[/COLOR][/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3]MyMessage = [/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#800000]"Please wait until the backup has completed."[/COLOR][/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Dim[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#000000] computers(1)[/COLOR][/SIZE][/FONT]
    [SIZE=3][FONT=Lucida Console]computers(0)=[/FONT][/SIZE][FONT=Lucida Console][SIZE=3][COLOR=#800000]"computer1"[/COLOR][/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3]computers(1)=[/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#800000]"computer2"[/COLOR][/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]For[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Each[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3] item [/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#0000ff]In[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3] computers[/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Set[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3] NSAgent = [/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#0000ff]CreateObject[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3]([/SIZE][/FONT][FONT=Lucida Console][SIZE=3][COLOR=#800000]"Altiris.AeXClient"[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3], computers(item))[/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Set[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3] SessionManager = NSAgent.SessionManager[/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Set[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3] Sessions = SessionManager.Sessions[/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Set[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3] Session = Sessions.Item(0)[/SIZE][/FONT]
    [SIZE=3][FONT=Lucida Console]MyReturn = Session.DisplayBalloon(MyTitle, MyMessage, MyIcon, 30, [/FONT][/SIZE][FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Nothing[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3])[/SIZE][/FONT]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]WScript[/COLOR][/SIZE][/FONT][FONT=Lucida Console][SIZE=3].Sleep(3000)[/SIZE][/FONT]
    [SIZE=3][FONT=Lucida Console]Session.HideBalloon(MyReturn)[/FONT][/SIZE]
    [FONT=Lucida Console][SIZE=3][COLOR=#0000ff]Next[/COLOR][/SIZE][/FONT]
    
    Thanks!
  14. jdean Altiris Engineer (Super Mod)

    How are you piping the computer names to the vbscript?

    Typically, you would use REDIM ARRAY(N)

    And do a For/Each and increment N by 1

  15. Brandon Active Member

    We are actually going to set all the computers up for the site in the vbs, then we are going to execute it from BackupExec. You can run pre/post jobs to stop services and notify the users when the backup is going, then the post task restarts the services and notifies them again that it is done. I am looking for an alternative to NET SEND basically.

    I am guessing I have an error because you can only createobject once. Is there such thing as ModifyObject so I can re-configure the instance of NSAgent each time through the loop?


    EDIT:
    This probably won't work though. I would have to wait 30 seconds between each machine getting the message. I may have to look into some alternatives because I think balloon tips are hidden on some of the machines.:banghead:
  16. ksweet New Member

    Much Much More Improved..

    :eek:mg:
    Code:
    '********************
    ' Copyright (c) 2008
    '         by
    '   Kenneth Sweet
    '********************
    On Error Resume Next
    
    'Message text to be displayed to the user
    MsgText = "This Message will be displayed to the user." & vbCrLf & "Please click on the OK button."
    'Title of message window
    MsgTitle = "Message Window Title"
    
    'How long to display the message window in number of seconds
    'Setting MsgDelay to 0 will display the message till the user responds / clicks on a button
    MsgDelay = 300
    
    'How long to show message before updating the countdown time in the message displayed to the user
    'if MsgDelay is set to 0 then CDDelay must also be set to 0
    'if MsgDelay is set to ano other value CDDelay must either be equal to MsgDelay so that the countdown time does not update
    '  or less than MsgDelay so the countdown time updates on a regular basis
    'if MsgDelay if greater than 0 then CDDelay can not be set to 0
    CDDelay = 10
    
    'Settings for how message window looks. Add values to get total
    'Select one value from each group. Buttons, Icon, Default Button, Msg Window Modal and add them togeather
    'MsgType
    'Buttons
    Const vbOKOnly = 0 'Display OK button only.
    Const vbOKCancel = 1 'Display OK and Cancel buttons.
    Const vbAbortRetryIgnore = 2 'Display Abort, Retry, and Ignore buttons.
    Const vbYesNoCancel = 3 'Display Yes, No, and Cancel buttons.
    Const vbYesNo = 4 'Display Yes and No buttons.
    Const vbRetryCancel = 5 'Display Retry and Cancel buttons.
    'Icon
    Const vbCritical = 16 'Display Critical Message icon.
    Const vbQuestion = 32 'Display Warning Query icon.
    Const vbExclamation = 48 'Display Warning Message icon.
    Const vbInformation = 64 'Display Information Message icon.
    'Default Button
    Const vbDefaultButton1 = 0 'First button is the default.
    Const vbDefaultButton2 = 256 'Second button is the default.
    Const vbDefaultButton3 = 512 'Third button is the default.
    Const vbDefaultButton4 = 768 'Fourth button is the default.
    'Msg Window Modal
    Const vbApplicationModal = 0 'Application modal. The user must respond to the message box before continuing work in the current application.
    Const vbSystemModal = 4096 'System modal. On Win16 systems, all applications are suspended until the user responds to the message box. On Win32 systems, this constant provides an application modal message box that always remains on top of any other programs you may have running.
    'Use vbOKOnly (buttons) when calling ShowUserMsgProcess
    MsgType = vbOKOnly + vbExclamation + vbDefaultButton1 + vbSystemModal
    
    'used in ShowUserMsgProcess only
    'Name of process to look for
    ProName = "cmd.exe"
    'Kill the proccess after count down or if user clicks OK
    KillPro = True 'True or False
    
    
    ' *****************************************************************************
    ' * Start Sample Code Un-Rem one of the 2 lines below
    ' *****************************************************************************
    'If a user is logged on show them a message
    TempReturn = ShowUserMsg(MsgText, MsgTitle, MsgDelay, CDDelay, MsgType)
    
    'If a user is logged on show them a message if a process is running
    'TempReturn = ShowUserMsgProcess(MsgText, MsgTitle, MsgDelay, CDDelay, MsgType, ProName, KillPro)
    
    'Exit script with Returned value
    WScript.Quit TempReturn
    ' *****************************************************************************
    ' * End Sample Code
    ' *****************************************************************************
    
    ' *****************************************************************************
    ' * Display a mesg to user is anyone is logged on
    ' *****************************************************************************
    'Return Values
    '0 No user was logged on
    'vbOK 1 OK button was clicked.
    'vbCancel 2 Cancel button was clicked.
    'vbAbort 3 Abort button was clicked.
    'vbRetry 4 Retry button was clicked.
    'vbIgnore 5 Ignore button was clicked.
    'vbYes 6 Yes button was clicked.
    'vbNo 7 No button was clicked.
    'Custom 8 Timed out, automaticly closed
    'Custom 9 Proccess failed to terminate
    
    Function ShowUserMsgProcess(ByVal MsgText, ByVal MsgTitle, ByVal MsgDelay, ByVal CDDelay, ByVal MsgType, ByVal ProName, ByVal KillPro)
      'Will show a logged on user a message if a user is currently logged on and a specific proccess is running
      On Error Resume Next
      TempReturn = 0
      If MsgDelay > 0 And CDDelay = 0 Then
        CDDelay = 10
      ElseIf MsgDelay = 0 Then
        CDDelay = 0
      End If
      Set MsgShell = WScript.CreateObject("WScript.Shell")
      Do
        ProRunning = FindProcess(".", ProName)
        If ProRunning Then
          If UserLoggedOn(".", UserName) Then
            Do
              If MsgDelay < CDDelay Then
                CDDelay = MsgDelay
              End If
              TempReturn = MsgShell.Popup(MsgDelayText(MsgDelay, MsgText), CDDelay, MsgTitle, MsgType)
              MsgDelay = MsgDelay - CDDelay
            Loop While TempReturn = -1 And MsgDelay > 0
            If KillPro Then
              If Not(KillProcess(CompName, ProName)) Then
                TempReturn = 9
              End If
            Else
              TempReturn = 9
            End If
          Else
            If KillPro Then
              If Not (KillProcess(CompName, ProName)) Then
                TempReturn = 9
              End If
            Else
              TempReturn = 9
            End If
          End If
        End If
      Loop While ProRunning And TempReturn <> 9 And MsgDelay > 0
      If TempReturn = -1 Then
        TempReturn = 8
      End If
      ShowUserMsgProcess = TempReturn
    End Function
    
    Function ShowUserMsg(ByVal MsgText, ByVal MsgTitle, ByVal MsgDelay, ByVal CDDelay, ByVal MsgType)
      'Will show a logged on user a message if a user is currently logged on, displayed message will have a timmer that will count down
      On Error Resume Next
      TempReturn = 0
      If MsgDelay > 0 And CDDelay = 0 Then
        CDDelay = 10
      ElseIf MsgDelay = 0 Then
        CDDelay = 0
      End If
      Set MsgShell = WScript.CreateObject("WScript.Shell")
      If UserLoggedOn(".", UserName) Then
        Do
          If MsgDelay < CDDelay Then
            CDDelay = MsgDelay
          End If
          TempReturn = MsgShell.Popup(MsgDelayText(MsgDelay, MsgText), CDDelay, MsgTitle, MsgType)
          MsgDelay = MsgDelay - CDDelay
        Loop While TempReturn = -1 And MsgDelay > 0
      End If
      If TempReturn = -1 Then
        TempReturn = 8
      End If 
      ShowUserMsg = TempReturn
    End Function
    
    Function MsgDelayText(ByVal MsgDelay, ByVal MsgText)
      'Returns Message text with remaining time added on to the end
      TempReturn = MsgText
      If MsgDelay > 0 Then
        MsgHour = Int(MsgDelay / 3600)
        MsgDelay = MsgDelay Mod 3600
        MsgMin = Int(MsgDelay / 60)
        MsgSec = MsgDelay Mod 60
        TempReturn = TempReturn & vbCrLf & vbCrLf & "This message will automaticly close in " & RetTime(MsgHour, MsgMin, MsgSec)
      End If
      MsgDelayText = TempReturn
    End Function
    
    Function RetTime(ByVal TempHour, ByVal TempMin, ByVal TempSec)
      'Returns imputed time as a string Hours, Minutes, and Seconds - 00:00:00
      RetTime = Num2Str(TempHour) & ":" & Num2Str(TempMin) & ":" & Num2Str(TempSec)
    End Function
    
    Function Num2Str(ByVal TempNum)
      'Returns number as a 2 character string
      Num2Str = Right("00" + CStr(TempNum), 2)
    End Function
    
    Function UserLoggedOn(ByVal CompName, ByRef UserName)
      'Return Values
      '-1 or True - A User is logged on
      '0 or False - No user was logged on
      On Error Resume Next
      TempReturn = False
      UserName = Null
      If ConnectWMI(CompName, "root\CIMV2", "", "", WMIConnection) Then
        Set ComputerInfo = WMIConnection.ExecQuery("SELECT UserName FROM Win32_ComputerSystem",, 48)
        For Each User In ComputerInfo
          If Not IsNull(User.UserName) Then
            UserName = User.UserName
            TempReturn = True
          End If
        Next
      End If
      UserLoggedOn = TempReturn
    End Function
    
    Function KillProcess(ByVal CompName, ByVal ProName)
      On Error Resume Next
      TempReturn = False
      If ConnectWMI(CompName, "root\CIMV2", "", "", WMIConnection) Then
        TempReturn = True
        'Get collection of all ProcessIDs where the name matches ProName
        Set ProcessList = WMIConnection.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & ProName & "'",, 48)
        'Loop through entire collection
        For Each TempProcess In ProcessList
          If TempProcess.Terminate() = 0 Then
            WScript.Sleep(1000)
            If FindProcess(CompName, ProName) Then
              TempReturn = TempReturn And False
            Else
              TempReturn = TempReturn And True
            End If
          Else
            TempReturn = TempReturn And False
          End If
        Next
      End If
      KillProcess = TempReturn
    End Function
    
    Function FindProcess(ByVal CompName, ByVal ProName)
      On Error Resume Next
      TempReturn = False
      If ConnectWMI(CompName, "root\CIMV2", "", "", WMIConnection) Then
        TempReturn = False
        'Get collection of all ProcessIDs where the name matches ProName
        Set ProcessList = WMIConnection.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & ProName & "'",, 48)
        'Loop through entire collection
        For Each TempProcess In ProcessList
          If LCase(TempProcess.Name) = ProName Then
            TempReturn = True
          End If
        Next
      End If
      FindProcess = TempReturn
    End Function
    
    Function ConnectWMI(ByVal CompName, ByVal NameSpace, ByVal UserName, ByVal Password, ByRef WMIConnection)
      On Error Resume Next
      Set WSNetwork = CreateObject("Wscript.Network")
      If LCase(CompName) = LCase(WSNetwork.ComputerName) Then
        UserName = ""
        Password = ""
      End If
      Set SWbemLocator = CreateObject("WbemScripting.SWbemLocator")
      If Err.number = 0 Then
        Set WMIConnection = SWbemLocator.ConnectServer(CompName, NameSpace, UserName, Password)
        If Err.number = 0 Then
          WMIConnection.Security_.impersonationlevel = 3
          ConnectWMI = True
        Else
          Err.Clear
          ConnectWMI = False
        End If
      Else
        Err.Clear
        ConnectWMI = False
      End If
    End Function
    
    
  17. masonje New Member

    Balloon when user not logged in

    We found in our software delivery packages that if you don't have any one logged in for the software delivery, the script hangs on the balloon and the agent stops the task when it hits the timeout. Here is the code we created to get around this. Hope this helps...

    Code:
    
    set objAltirisAgent = nothing
    Set objWshShell = WScript.CreateObject("WScript.Shell")
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    'check for the altiris agent.  If exists, the objAltirisAgent object is set
    dim strAltirisDir, strAltirisReg
    strAltirisDir = "c:"
    strAltirisReg = "HKEY_LOCAL_MACHINE\SOFTWARE\Altiris\Altiris Agent\InstallDir"
    if RegVerify(strAltirisReg) then
        strAltirisDir = objWshShell.RegRead(strAltirisReg)
    end if
    If objFSO.FileExists(strAltirisDir & "\AeXAgentActivate.exe") Then
        set objAltirisAgent = CreateObject("Altiris.AeXClient")
    else
        set objAltirisAgent = Nothing
    End if
    
    
    
    
    'code here
    
    AltirisBubble "Title", "Message Here", 3, 30
    
    wscript.quit()
    
    
    'end code
    
    'start sub
    Public Function RegVerify(ByVal sRegEntry)
        On Error Resume next
        Dim WSH, sKeyTmp
        Set WSH=CreateObject("WScript.Shell")
        sKeyTmp = WSH.RegRead (sRegEntry)
        if err.number=0 then
            RegVerify = True
            Addlog objFile, sRegEntry & " was found",Talk
        else
            RegVerify = False               
            Addlog objFile, sRegEntry & " was NOT found",Talk
        end if
        err.clear
        On Error goto 0
    End Function
    
    Sub AltirisBubble(strTitle, strMsg, intIcon, intTime)
        if numLoggedinUsers() > 0 then
            if not objAltirisAgent is nothing then
                dim sessmgr, sessions, session, cookie
                set sessmgr = objAltirisAgent.SessionManager
                set sessions = sessmgr.Sessions
                Set session = sessions.Item ( 0 )
                
                'intIcon info
                ' 0 = No Icon
                ' 1 = Information Icon
                ' 2 = Warning Icon
                ' 3 = Error Icon
                ' 4 = Altiris
                
                cookie = session.DisplayBalloon ( "", "", intIcon, 0, Nothing)
                WScript.Sleep 10
                cookie = session.DisplayBalloon ( strTitle, strMsg, intIcon, intTime, Nothing)
                'AddLog objFile, "Altiris balloon: " & strTitle & ", " & strMsg & ", " & intIcon & ", " & intTime,Talk
                
                set sessmgr = Nothing
                set sessions = Nothing
                set session = Nothing
            end If
        else
            'AddLog objFile, "No user logged in for Altiris Bubble" 
        end if
    End Sub
    
    'returns the number of users logged on
    function numLoggedinUsers()
        Dim objWMIService
        Dim intUserLoggin
        
        strComputer = "."  
        Set objWMIService = GetObject("winmgmts:" _  
            & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")  
            Set colComputer = objWMIService.ExecQuery _  
            ("Select * from Win32_ComputerSystem") 
            
        intUserLoggin = 0
        
        For Each objComputer in colComputer
            if objComputer.UserName <> "" then
                intUserLoggin = intUserLoggin + 1
            end if
        Next
        numLoggedinUsers = intUserLoggin
    end function
    

Share This Page