Script to display a pop-up and then kills a windows process - windows

I'm trying to deploy an application through SCCM 2012 for Windows7 (x86 and x64) that requires to notify the user that his Microsoft Outlook should be closed before to continue with the installation. It could be either with a Timer or a (Yes / No) choice, then if the user press Yes then it will close Outlook and will continue with the installation otherwise it will send a log file saying the the user cancelled the installation but it can be retried at any time.
So far I just have the installation script that works only to install the applications using a command line script. So, it will just execute some MSI's installations and Windows updates, and then it quits.
The script I have that creates the pop up and that can be called by my CMD file is the following VBScript and was taken from a TechNet article.
Const TIMEOUT = 7
Set objShell = WScript.CreateObject("WScript.Shell")
Set objFS = WScript.CreateObject("Scripting.FileSystemObject")
strPath = Wscript.FullName
strFileVersion = objFS.GetFileVersion(strPath)
iRetVal = objShell.Popup(Wscript.FullName & vbCrLf & _
"File Version: " & _
strFileVersion & vbCrLf & _
"Would you like to close Outlook application and continue with the installation?" _
,TIMEOUT,"Outlook Validation",vbYesNo + vbQuestion)
Select Case iRetVal
Case vbYes
Set objFile = objFS.GetFile(strPath)
objShell.Popup WScript.FullName & vbCrLf & vbCrLf & _
"File Version: " & strFileVersion & vbCrLf & _
"File Size: " & Round((objFile.Size/1024),2) & _
" KB" & vbCrLf & _
"Date Created: " & objFile.DateCreated & vbCrLf & _
"Date Last Modified: " & objFile.DateLastModified & _
vbCrLf,TIMEOUT
Wscript.Quit
Case vbNo
Wscript.Quit
Case -1
WScript.StdOut.WriteLine "Popup timed out."
Wscript.Quit
End Select
So I don't know if there's any useful example that I can use and customize it from there. I'm clueless, blindfolded, I don't see the light. Well you understand my frustration.
Any ideas, examples or links will be really appreciated!!
Thanks & kind regards.
Joel.

This is one way.
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")
For Each objItem in colItems
'msgbox objItem.name & " " & objItem.CommandLine
If LCase(objItem.name) = "outlook.exe" then
If Msgbox("Close Outlook", 33, "Install") = 1 then
objItem.terminate
End If
End If
Next
VBScript's Help file - https://www.microsoft.com/en-au/download/details.aspx?id=2764
For help with the WMI object use wmic at the command prompt.
wmic process get /? (same as wmic path win32_process get /?) and wmic process call /? list properties and methods.

Here my procedure which closes outlook before modifying the profile.
Is is part of a logon script. The show is a logging and informing procedure.
sub CloseOutlook
on error resume next 'to be able to log and continue
dim objWMIService, colProcessList, objProcess, sResult, oShell
set oShell = WScript.CreateObject("WScript.Shell")
set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
set colProcessList = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = 'OUTLOOK.EXE'")
for Each objProcess in colProcessList
show "outlook is being closed"
objProcess.Terminate()
if Err <> 0 then
show "Error while closing outlook: " & err.Description
end if
sResult = oShell.Popup("Outlook is being closed, profile is configured")
next
end sub
If you want confirmation from the user you will have to use a MsgBox instead.

I'd recommend not faffing about with warnings and closing Outlook, but instead configure the advert to run when no users are logged in. Less chance for problems or accidentally miss-clicked "oh no you lost my emails" situations.

Related

VBScript - Multiple Issues

So I've been thrown in the deep end of the shark tank without even my arm floaters and I don't know how to swim (Translation - I don't know VBS).
So I find myself here because I keep hitting my scripts with the two sticks I have it still doesn't work. When I fix one issue another appears and when I fix that one the other returns (feel like I'm chasing my tail).
So below is the latest iteration of my code (I keep moving crap around thinking it might magically work).
'---- Set Constant for Reading
Const ForReading = 1
'----- Define at the Variables for the scripts
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
'------ Path for File below is Explicit (meaning you need to enter the complete path)
Set objTextFile = objFSO.OpenTextFile("c:\users\me\documents\Small- ComputerList.txt", ForReading)
'---- Begin Loop for reading the Array
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
arrServiceList = Split(strNextLine , ",")
' ------- strComputer = "usms-w-ksd68598" Commented out from original script
' ------- Reading from the Array
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & arrServiceList(0) & "\root\cimv2")
' ------- Running the Command to find all the printers
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer")
For Each objPrinter in colPrinters
objDictionary.RemoveAll
objDictionary.Add objPrinter.PortName, objPrinter.PortName
Next
' ------ Running the Command to find all the TCP/IP Printer Ports
Set colPorts = objWMIService.ExecQuery _
("Select * from Win32_TCPIPPrinterPort")
For Each objPort in colPorts
If objDictionary.Exists(objPort.Name) Then
strUsedPorts = strUsedPorts & _
objDictionary.Item(objPort.Name) & VbCrLf
Else
strFreePorts = strFreePorts & objPort.Name & vbCrLf
End If
Next
'----- Printing out the Results to the screen
For i = 1 to Ubound(arrServiceList)
& arrServiceList(i)
Next
Loop
Wscript.Echo "System Name: " & arrServiceList(0)
Wscript.Echo "The following ports are in use for: " & VbCrLf & strUsedPorts
Wscript.Echo "The following ports are not used for: " & VbCrLf & strFreePorts
If my crazy ducted taped scripts make no sense please don't be shocked. I've been stuck in a cave hitting the keyboard with two sticks and this is the result I've come up with. Not too bad for a caveman but it still doesn't work.
Any help, assistance, advice, comment, jokes, sarcasm, ranting appreciated. Any trolling will be swiftly dealt with a big mallet over the head.
Thank you,
Ed Medina
Lo and behold the gods of code have shine their light upon my path and provided me with an answer.
Anyway, Thanks to Big Chris and Mr. Roryap for their questions. I want to also thank the Academy, all of my fellow coders, my mom, coffee, the mailman, my wife, my cat and all the little people.
Here is a code that will work which will read from a file in your Temp Folder (file is named Computers.txt) and then against that file it will run and test to find all the printers ports in that computer in your Domain (Network).
The output is a simple Echo out giving it to you in the window. I just kept hitting the keyboard with my two sticks in my dark, smelly cave and out came out the code.
The only caveat is that if you have a wrong computer name or a computer turned off the script will fail at that point and won't continue (yeah, yeah, working on it).
'---- Set Constant for Reading
Const ForReading = 1
'----- Define at the Variables for the scripts
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
'------ Path for File below is Explicit (meaning you need to enter the complete path)
Set objFile = objFSO.OpenTextFile("c:\Temp\Computers.txt", ForReading)
'---- Begin Loop for reading the Array
Do Until objFile.AtEndOfStream
strComputer = objFile.ReadLine
' ------- Reading from the Array
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
' ------- Running the Command to find all the printers
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer")
For Each objPrinter in colPrinters
objDictionary.RemoveAll
objDictionary.Add objPrinter.PortName, objPrinter.PortName
Next
' ------ Running the Command to find all the TCP/IP Printer Ports
Set colPorts = objWMIService.ExecQuery _
("Select * from Win32_TCPIPPrinterPort")
For Each objPort in colPorts
If objDictionary.Exists(objPort.Name) Then
strUsedPorts = strUsedPorts & _
objDictionary.Item(objPort.Name) & VbCrLf
Else
strFreePorts = strFreePorts & objPort.Name & vbCrLf
End If
Next
'---- Output to Screen
Wscript.Echo "System Name: " & strComputer
Wscript.Echo "The following ports are in use for: " & VbCrLf & strUsedPorts
Wscript.Echo "The following ports are not used for: " & VbCrLf & strFreePorts
Loop
Thank you.
BTW if anyone know how to throw an error and keep working give feel free to post. Thanks again everyone.

How to check the current windows command prompt is hidden by using vbscript or command lines

I want to detecting if the current running bat script is hidden by the caller, that means (nCmdShow=0) for example.
There is windows API to get this information, GetStartupInfo, but it can not be called by command prompt or VBScript(without third party libraries).
The following script can retrieve the startup information, but the problem is that's only works under WinXp, it's doesn't work under Win7. I am looking for a way can support across winxp - win8.
Dim wmiService
Set wmiService = GetObject("winmgmts:\\.\root\cimv2")
Dim startupInfo
Set startupInfo = wmiService.Get("Win32_ProcessStartup")
The following code works fine under xp, but doesn't work under win7, it's show all the startup information.
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_ProcessStartup",,48)
For Each objItem in colItems
Wscript.Echo "CreateFlags: " & objItem.CreateFlags
Wscript.Echo "EnvironmentVariables: " & objItem.EnvironmentVariables
Wscript.Echo "ErrorMode: " & objItem.ErrorMode
Wscript.Echo "FillAttribute: " & objItem.FillAttribute
Wscript.Echo "PriorityClass: " & objItem.PriorityClass
Wscript.Echo "ShowWindow: " & objItem.ShowWindow
Wscript.Echo "Title: " & objItem.Title
Wscript.Echo "WinstationDesktop: " & objItem.WinstationDesktop
Wscript.Echo "X: " & objItem.X
Wscript.Echo "XCountChars: " & objItem.XCountChars
Wscript.Echo "XSize: " & objItem.XSize
Wscript.Echo "Y: " & objItem.Y
Wscript.Echo "YCountChars: " & objItem.YCountChars
Wscript.Echo "YSize: " & objItem.YSize
Next
There is a way of calling API calls in VBS or batch.
appactivate between multiple internet explorer instances
Although the sample given doesn't work 7 and later because of a name conflict. Rename sendmail to something else for 7 and later.
If a limited user you need to manually add the registry entries to hkcu\software\classes.

Start Service with VBscript

I am trying to have this script take a text file running and stopped services before a reboot and start any services that did not automatically start after the machine starts back up. The script that gets the list of service names, state and startmode and creates a comma separated text file line by line works fine. Here it is for reference (taken from the interwebs, lost the link in my travels. Modified slightly.):
Const ForAppending = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFSO.CreateTextFile("service_list.txt", _
ForWriting, True)
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service")
For Each objService in colListOfServices
objLogFile.Write objService.Name & ","
objLogFile.Write objService.StartMode & ","
objLogFile.Write objService.State
objLogFile.Writeline
Next
objLogFile.Close
This next bit reads the file line by line, compares the state of all of the services with the state of the services that were recorded before the machine was shut down. If they match, do nothing, if they are different, start the service:
Const ForReading = 1
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objServiceName = objWMIService.get("Win32_Service.Name='" & ServiceName & "'")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("\\some path\service_list.txt",ForReading,True,-2)
Do Until objFile.AtEndOfStream
fLine = Split(objFile.ReadLine,",")
'wscript.echo fLine(2)
if InStr(fLine(2),"Running") then
'wscript.echo "it was running!"
if objServiceName.Started then
'do nothing
else
'Set servicetostart = objWMIService.ExecQuery ("Select " & ServiceName & " from Win32_Service Where Name ='Alerter'")
'servicetostart.StartService()
'Result = objServiceName.StartService
'If 0 <> Result Then
' wscript.echo "Start " & ServiceName & " error:" & Result
'End If
objServiceName.StartService
'wscript.echo Servicename & "could not start with error: " & Result
end if
end if
'wscript.echo objServiceName
Loop
As of right now I am recieving an error whenever it actually tries to start the service. I receive a "Provider Failure code:80041004 Source:SWbemObjectEX". I have been looking through the posts about this error and attempting the fixes suggested. Also, as you can see, I have been trying variations, but I am afraid I am merely guessing.
So to my question, what is causing the "Provider Failure"? I have looked up these information for the Win32_Service Class here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394418%28v=vs.85%29.aspx#methods
and looked up the method here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa393660%28v=vs.85%29.aspx
But have been unable to work out where the I am going wrong.
Thanks,
Joe
on a side note, the service I am testing, ie. making sure the service is starting, creating the text file, then stopping the service and running the "start service" code is Windows Defender. The service name is "WinDefend".
FINAL WORKING CODE:
Const ForReading = 1
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("\\vmware-host\Shared Folders\Documents\Biffduncan\Monthly Server Maintanence\service_list.txt",ForReading,True,-2)
Do Until objFile.AtEndOfStream
fLine = Split(objFile.ReadLine,",")
Set objService = objWMIService.get("Win32_Service.Name='" & fLine(0) & "'")
if InStr(fLine(2),"Running") then
'wscript.echo "it was running!"
if objService.Started then
'do nothing
else
Result = objService.StartService()
if Result <> 0 then
wscript.echo "The service: " & objService.Name & " did not start with error: " & Result
else
wscript.echo "Service " & objService.Name & " started"
end if
end if
end if
Loop
Error code 0x80041004 means that the WMI provider encountered an error after it was already initialized. The error code doesn't say anything about the cause of the error, though, nor does it provide any details. Try running WBEMTest or WMIDiag to track down the error. Also check the eventlog for related errors/warnings. If everything else fails, try rebuilding the WMI repository.
As for your code, the first thing I'd do is strip it down to the bare minimum, to avoid potential error sources:
Set wmi = GetObject("winmgmts://./root/cimv2")
Set svc = wmi.Get("Win32_Service.Name='WinDefend'")
rc = svc.StartService
WScript.Echo rc
Also, I wouldn't recommend writing the service status to a file at some random point in time, and then try starting services according to the contents of that file. There is no guarantee that the start mode hasn't been changed since the file was created, or that the service is even installed anymore.
Whether or not a service should be started is indicated by its StartMode property, so just check those services that are set to Auto. Services set to Manual will be started by the system on demand, so there's no need to launch them just because they were running when you took the snapshot.
qry = "SELECT * FROM Win32_Service WHERE StartMode='Auto'"
For Each svc In wmi.ExecQuery(qry)
If Not svc.Started Then svc.StartService
Next

Show logging for a vbs script

I have a script i use for uninstalling an application
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colSoftware = objWMIService.ExecQuery _
("Select * from Win32_Product " _
& "Where Name = 'Personnel database'")
For Each objSoftware in colSoftware
Wscript.Echo "Name: " & objSoftware.Name
Wscript.Echo "Version: " & objSoftware.Version
objSoftware.Uninstall()
Next
The problem is i don't know if the
Has started running or has completed
uninstall has completed
Has completed
Is there a way to show this in a log file or a console.
Thanks
Uninstall has completed when Uninstall returns with return code 0. Having your script log something is entirely up to you, though. You could write stuff to a log file or the eventlog, show a MsgBox or write text to the console (when running with cscript.exe).
A while ago I wrote this to simplify the handling (if you'll forgive the shameless plug). You could use it like this:
'insert class code here
Set clog = New CLogger
clog.LogToConsole = False
clog.LogFile = "C:\path\to\your.log"
clog.IncludeTimestamp = True
clog.Log "Starting"
'...
For Each objSoftware in colSoftware
clog.Log "Uninstalling " & objSoftware.Name & " (v" & objSoftware.Version & ")"
rc = objSoftware.Uninstall()
If rc = 0 Then
clog.Log "Uninstall complete"
Else
clog.LogError "An error occurred: " & rc
End If
Next
clog.Log "Finished"
You could always put msgbox in your script in your for each loop
MsgBox("Uninstalling " + objSoftware.Name)
or you could do a simple in your for each loop
Wscript.Echo "Uninstalling " + objSoftware.Name
Just run your vbs from admin command prompt window open
wscript uninstallfile.vbs
This will show up in your command console.

Can't get WMI namespace RSOP to work

I need to create a subroutine to check for certain policies on a system. I'm currently just trying to do that.
strComputerFQDN is defined at the beginning of the program and that is working fine.
Do you see anything wrong?
Here is my code:
'*************************************************************************
' This Subroutine checks Local Policies
'*************************************************************************
Sub CheckPolicies()
Dim objGPOSrvc,colItems,objItem
Set objGPOSrvc = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputerFQDN & "\root\RSOP")
Set colItems = objGPOSrvc.ExecQuery("SELECT * FROM RSOP_GPO")
WScript.Echo("Check Policies")
WScript.Echo("------------------------------------")
For Each objItem in colItems
If InStr(UCase(objItem.Name),"WSUS") Then
If InStr(UCase(objItem.Name),"SERVER") Then
WScript.Echo("Policy applied: " & objItem.Name)
Else
WScript.Echo("Wrong WSUS Policy Applied - Check Computer object location")
End If
End If
Next
If strWSUSApplied = "FALSE" Then
WScript.Echo("No WSUS Policy Applied!")
End If
WScript.Echo vbCrLf
End Sub
The namespace should be root\RSOP\Computer
Set objGPOSrvc = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputerFQDN & "\root\RSOP\Computer")
or root\RSOP\User
Set objGPOSrvc = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputerFQDN & "\root\RSOP\User")
Most typically you would do something like this:
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\RSOP\Computer")
Set colItems = objWMIService.ExecQuery("Select * from RSOP_GPO")
For Each objItem in colItems
WScript.Echo "Name: " & objItem.Name
WScript.Echo "GUID Name: " & objItem.GUIDName
WScript.Echo "ID: " & objItem.ID
WScript.Echo "Access Denied: " & objItem.AccessDenied
WScript.Echo "Enabled: " & objItem.Enabled
WScript.Echo "File System path: " & objItem.FileSystemPath
WScript.Echo "Filter Allowed: " & objItem.FilterAllowed
WScript.Echo "Filter ID: " & objItem.FilterId
WScript.Echo "Version: " & objItem.Version
WScript.Echo
Next
If you receive Error 0x80041003, you will need to run this script with administrator credentials. For Vista and later, open your start menu and type cmd. When "Command Prompt" appears, right-click and choose Run As Administrator. You can now launch your script from the elevated command prompt without error.

Resources