I have a script which allows me to grab certain machine info when a user runs the script, and the result gets written on a text file on a server share. The script works fine...however, I would like for it not to repeat the headers when the next user runs the script. I searched around the forums but couldn't find anything that would allow me to accomplish this. Apologies if my language is dull. I'm sure it's something pretty easy and would appreciate if someone could give me some pointers. I'm not a programmer but I'm very fascinated on writing scripts that makes my job easier.
Currently, this is how the result looks like.
User Name, Host Name, Manufacturer, Serial Number, Operating System, Model
CA\username, NAPHX-C63E90K-L, LENOVO, PC63E90K, Microsoft Windows 7 Enterprise 6.1.7601, 20AMS1UD00
User Name, Host Name, Manufacturer, Serial Number, Operating System, Model
CA\username, USAPHX-6GL4R7-L, LENOVO, PC6GL4R7, Microsoft Windows 10 Enterprise 10.0.17134, 20FMS3XC00
User Name, Host Name, Manufacturer, Serial Number, Operating System, Model
CA\username, USAPHX-6KTBAY-L, LENOVO, PC6KTBAY, Microsoft Windows 10 Enterprise 10.0.17134, 20EQS2NM00
User Name, Host Name, Manufacturer, Serial Number, Operating System, Model
CA\username, MEXMEC-6Z0A6U-L, LENOVO, PC6Z0A6U, Microsoft Windows 10 Enterprise 10.0.17763, 20L8S6G20E
I want it to look like this instead.
User Name, Host Name, Manufacturer, Serial Number, Operating System, Model
CA\username, NAPHX-C63E90K-L, LENOVO, PC63E90K, Microsoft Windows 7 Enterprise 6.1.7601, 20AMS1UD00
CA\username, USAPHX-6GL4R7-L, LENOVO, PC6GL4R7, Microsoft Windows 10 Enterprise 10.0.17134, 20FMS3XC00
CA\username, USAPHX-6KTBAY-L, LENOVO, PC6KTBAY, Microsoft Windows 10 Enterprise 10.0.17134, 20EQS2NM00
CA\username, MEXMEC-6Z0A6U-L, LENOVO, PC6Z0A6U, Microsoft Windows 10 Enterprise 10.0.17763, 20L8S6G20E
Here's a sample of my current script.
' On Error Resume Next
' Constants for FileSystemObject
Const FOR_READING = 1
Const FOR_WRITING = 2
Const FOR_APPENDING = 8
strFileOutput = "\\servershare\folder\info.txt"
' Create a Script Runtime FileSystemObject.
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Check to see if the output file exists. If so, open it for writing or appending.
' If not, create it and open it for writing.
If objFSO.FileExists(strFileOutput) Then
Set objOutputFile = objFSO.OpenTextFile (strFileOutput, FOR_APPENDING)
Else
Set objOutputFile = objFSO.CreateTextFile(strFileOutput)
End If
If Err <> 0 Then
Wscript.Echo "Unable to open " & strFileOutput & " for output."
WScript.Quit
End If
'Create Headers for Host, Manufacturer, Serial Number
objOutputFile.Writeline "User Name, Host Name, Manufacturer, Serial Number, Operating System, Model"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colSettings = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem")
For Each objComputer in colSettings
PCMfg = objComputer.Manufacturer
PCName = objComputer.Name
UserName = objComputer.UserName
'Wscript.Echo "User: " & Manufacturer: " & PCMfg & VbCrLf & "PC Name: " & PCName
NEXT
Set colBIOS = objWMIService.ExecQuery ("Select * from Win32_BIOS")
For each objBIOS in colBIOS
SerNo = objBIOS.SerialNumber
'Wscript.Echo "Serial Number: " & SerNo
NEXT
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
OS = objOperatingSystem.Caption & " " & objOperatingSystem.Version
'Wscript.Echo "Operating System: " & objOperatingSystem.Caption & " " & objOperatingSystem.Version
Next
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("SELECT Version FROM Win32_ComputerSystemProduct")
For Each objItem in colItems
Model = objItem.Name
'Wscript.Echo "Model: " & objItem.Name
Next
objOutputFile.Writeline Username & ", " & PCName & ", " & PCMfg & ", " & SerNo & ", " & OS & ", "& Model
objOutputFile.Close
x=msgbox("Process is now complete. Thank you for your time!" ,0, "PC Info Complete")
Move the line that creates the headers to the file exists check, so that they are created only once per file:
If objFSO.FileExists(strFileOutput) Then
Set objOutputFile = objFSO.OpenTextFile (strFileOutput, FOR_APPENDING)
Else
Set objOutputFile = objFSO.CreateTextFile(strFileOutput)
'moved this line
'Create Headers for Host, Manufacturer, Serial Number
objOutputFile.Writeline "User Name, Host Name, Manufacturer, Serial Number, Operating System, Model"
End If
Im looking for some help with creating a script that can scan the Disk Drives on a Server or PC and search out a Zepto Virus infection and alert us in our Monitoring Dashboard.
We have used scripts to detect Cryptowall and Locky but these rely on searching for a very specific file name. The difference with Zepto is that its "Help" files are composed with a random number in each file:
_3_HELP_instructions.html, _21_HELP_instructions.html, _12_HELP_instructions.html etc.
Essentially im looking for a script that can maybe search for *_HELP_instructions.html or even just search for any filename with HELP_instructions.html contained in it.
The code we have used for Locky is as follows:
strComputer = "."
set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colShares = objWMIService.ExecQuery("Select * from Win32_Share")
For each objShare in colShares
strInfected = False
If objFSO.fileexists(objShare.path & "\_Locky_recover_instructions.txt") then
strInfected = True
wscript.echo "Network Share " & objShare.Path & " is INFECTED!"
wscript.quit(2015)
End If
Next
If strInfected = False Then
wscript.echo "System Clear!"
wscript.quit(0)
End If
Is there anyone out there that can help me with this one? due to the way our Monitoring Dashboard works i need the script to be based on the above, with the:
If strInfected = False Then
wscript.echo "System Clear!"
wscript.quit(0)
End If
at the end of the script.
Many thanks in advance
As the title indicates, I'm currently unable to retrieve a list of virtual machines with a WMI query in VBScript. Hyper-V manager is correctly identifying 3 Virtual Machines on the Host in question, but when I query WMI I only see the Host itself.
Here's a sample VBScript (courtesy of WMI Code Creator):
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\virtualization\v2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem",,48)
For Each objItem in colItems
Wscript.Echo "-----------------------------------"
Wscript.Echo "Msvm_ComputerSystem instance"
Wscript.Echo "-----------------------------------"
Wscript.Echo "Description: " & objItem.Description
Wscript.Echo "ElementName: " & objItem.ElementName
Next
Output:
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
-----------------------------------
Msvm_ComputerSystem instance
-----------------------------------
Description: Microsoft Hosting Computer System
ElementName: TEST-VH
Ideas, suggestions, or rocks to look under would be greatly appreciated, thanks!
You can take it one level higher and grab the computer names directly then compare the model and extract accordingly. I do not have any VM's installed to try this. But give it a shot and let me know if it works.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
For Each objItem in colItems
strModel = objItem.Model
If instr(strModel, "Virtual Machine") Then
Wscript.Echo "-----------------------------------"
Wscript.Echo "Msvm_ComputerSystem instance"
Wscript.Echo "-----------------------------------"
Wscript.Echo "Description: " & objItem.Description
Wscript.Echo "HostName: " & objItem.Name
End if
Next
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
I am using VbScript for retrieving the securitydescriptor of a Win32_Service. I am using the following code:
SE_DACL_PRESENT = &h4
ACCESS_ALLOWED_ACE_TYPE = &h0
ACCESS_DENIED_ACE_TYPE = &h1
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate, (Security)}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * from Win32_Service")
For Each objPrinter in colInstalledPrinters
Wscript.Echo "Name: " & objPrinter.Name
' Get security descriptor for printer
Return = objPrinter.GetSecurityDescriptor( objSD )
If ( return <> 0 ) Then
WScript.Echo "Could not get security descriptor: " & Return
wscript.Quit Return
End If
' Extract the security descriptor flags
intControlFlags = objSD.ControlFlags
If intControlFlags AND SE_DACL_PRESENT Then
' Get the ACE entries from security descriptor
colACEs = objSD.DACL
For Each objACE in colACEs
' Get all the trustees and determine which have access to printer
WScript.Echo objACE.Trustee.Domain & "\" & objACE.Trustee.Name
If objACE.AceType = ACCESS_ALLOWED_ACE_TYPE Then
WScript.Echo vbTab & "User has access to printer"
ElseIf objACE.AceType = ACCESS_DENIED_ACE_TYPE Then
WScript.Echo vbTab & "User does not have access to the printer"
End If
Next
Else
WScript.Echo "No DACL found in security descriptor"
End If
Next
However, every time I run it I get the message saying the resulting code is -2147023582 something, rather than the error codes defined in
the manual.
Anyone got any ideas? I am using Windows 7 professional 64-bit.
The number is -2147023582. Could it be some sort of 64-bit issue? doesn't that look like a unsigned integer stored as a signed integer?
(PS: don't mind the variablenames... I ripped an example off of msdn).
The error code -2147023582 (0x80070522) means "A required privilege is not held by the client." Most likely, the Security privilege in the WMI moniker is not enough, and you need to run your script as Administrator. (At least, your script works fine for me on 64-bit Vista when run as admin.)