I'm fairly new at scripting and am having to rapidly make up for a
number of "admins" being let go at our company. There are a lot of
daily tasks I'm working on scripting and one of them is collecting
event logs.
I snagged a nice little script off of Technet and did some minor
modifications to be able to save the event logs with a custom file
name (includes date and machine name) to a fileshare on a server. It
pulls a list of servers to get event logs off of from a text file and
promptly goes and saves them and clears them (clearing commented out
until I get this problem solved).
The problem is that I want ALL the event logs dumped up to one file
share, not saved locally. The script below works if I modify it to
write to the local drive on the servers, but won't work using a share,
even though it's shared with Everyone having Full Control and NTFS
perms are Everyone/FC as well (this is temporary, I'll restrict it
when I figure out what accounts it's trying to use).
If anyone can point me in the right direction for this, I'd really
appreciate it. The script is below... apologies if it wraps due to
newsreader, there are a few lines that I think I can't break correctly
with the underscore, so I left it - in short, if a line looks like it
shouldn't be there, it probably belongs on the one above. If anyone
would like the regular version without dealing with wrapping, I can
zip it and post it.
By the way, I am the one running the script and I am a domain admin as
well as a local admin (explicitly & inherited) on the file server.
'__________________________________________
Const ForReading = 1
'Start Get Date
dtmThisDay = Day(Date)
dtmThisMonth = Month(Date)
dtmThisYear = Year(Date)
strBackupName = dtmThisYear & "_" & dtmThisMonth & "_" &
dtmThisDay
' Start file open and read in servers - add servers to
collection objDictionary
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("c:\scripts\servers.txt",
ForReading)
i = 0
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
objDictionary.Add i, strNextLine
i = i + 1
Loop
For Each objItem in objDictionary
strComputer = objDictionary.Item(objItem)
Set objWMIService = GetObject("winmgmts:" &
"{impersonationLevel=impersonate,(backup)}!\\" & strComputer &
"\root\cimv2")
Set colLogFiles = objWMIService.ExecQuery ("Select * from
Win32_NTEventLogFile where LogFileName='Application'")
For Each objLogfile in colLogFiles
objLogFile.BackupEventLog("\\pc3h23\EventLogs\" &
strBackupName & "_" & strComputer & "_app.evt")
' Remove this line and the next when save works
' objLogFile.ClearEventLog()
Next
Next
> Hey all,
>
> I'm fairly new at scripting and am having to rapidly make up for a
> number of "admins" being let go at our company. There are a lot of
> daily tasks I'm working on scripting and one of them is collecting
> event logs.
>
> I snagged a nice little script off of Technet and did some minor
> modifications to be able to save the event logs with a custom file
> name (includes date and machine name) to a fileshare on a server. It
> pulls a list of servers to get event logs off of from a text file and
> promptly goes and saves them and clears them (clearing commented out
> until I get this problem solved).
>
> The problem is that I want ALL the event logs dumped up to one file
> share, not saved locally. The script below works if I modify it to
> write to the local drive on the servers, but won't work using a share,
> even though it's shared with Everyone having Full Control and NTFS
> perms are Everyone/FC as well (this is temporary, I'll restrict it
> when I figure out what accounts it's trying to use).
>
> If anyone can point me in the right direction for this, I'd really
> appreciate it.
Hi
The BackupEventLog supports UNC addresses, so that is not the issue. I modified
your script to make a backup of my local computers event log to a UNC address,
and that worked. I guess that would be the same for you.
I think this is your problem:
Your process on the remote computer does not have access to any network
resources when using NTLM authentication, which is the default.
When you use NTLM authentication, after the impersonation, the process/thread
can only access local resources.
If you use Kerberos authentication instead, you should be able to access network
resources, but to use Kerberos, you need AD and Win2k/WinXP computers.
Platform SDK: WMI
Setting the Authentication Type Using VBScript
http://msdn.microsoft.com/library/en-us/wmisdk/wmi/setting_the_authentication_type_using_vbscript.asp
WMI SWbemLocator.ConnectServer
http://msdn.microsoft.com/library/en-us/wmisdk/wmi/swbemlocator_connectserver.asp
A couple of examples using Kerberos authentication:
Install Software on a Remote Computer
http://www.microsoft.com/technet/scriptcenter/compmgmt/ScrCM28.asp
Subject: Win32_Process.Create and network shares
Newsgroups: microsoft.public.win32.programmer.wmi
Date: 2002-05-15 07:53:32 PST
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&th=51dd2ec80ae16b5
More info on Kerberos:
Kerberos Explained (Windows 2000 Advantage Magazine Article)
http://www.microsoft.com/TechNet/prodtechnol/windows2000serv/maintain/kerberos.asp
Windows 2000 Kerberos Authentication White Paper
http://www.microsoft.com/technet/prodtechnol/windows2000serv/deploy/kerberos.asp
============================================================
A workaround (when using NTLM authentication), seems to be to use
NullSessionShares:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q122702
and a couple of newsgroup articles:
From: Andrea Cuozzo (andrea...@reti.it)
Subject: Re: Remote software installs of MSI packages via WMI
Newsgroups: microsoft.public.wbem
Date: 2001-02-28 03:29:55 PST
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=OE4WxjXoAHA.2224%40tkmsftngp05
From: Brian Watkins (watk...@knews.com)
Subject: Launching a program remotely
Newsgroups: microsoft.public.wbem
Date: 2001-10-17 10:31:56 PST
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&th=63b102c2512583fd
============================================================
A second alternative is to use WSH 5.6 Remote scripting and let the remote
computer map a drive:
A Michael Harris qoute:
"Change the calling script to prompt for username/password and pass them to the
remote script as commandline arguments. Change the remote script to map a
network drive on the fly using the credentials using an unused drive letter.
Before exiting the remote script, unmap the drive."
Below is a Michael Harris example of a script that is passed credentials via
named arguments and maps/unmaps a drive.
It should work, here is the feedback from one who has used it:
Subject: Re: problem using CopyFile method in remote script
Date: 20 Sep 2002 06:34:56 -0700
From: david...@newisys.com (David Papas)
Newsgroups: microsoft.public.scripting.wsh
<qoute>
I wound up using the on-the-fly map, but am using a dedicated domain
account for those credentials.
</qoute>
'=================================================
' Calling syntax:
' myscript.vbs /u:<username> /p:<password>
'
' Both named arguments are required...
'
' Error codes thrown:
' 100 - username and/or password missing
' 200 - ConnectDrive failed
'=================================================
sShare = "\\server\share"
sUsername = Null
sPassword = Null
Set Named = WScript.Arguments.Named
If Named.Exists("u") Then
sUsername = Named.Item("u")
End If
If Named.Exists("p") Then
sPassword = Named.Item("p")
End If
If IsNull(sUsername)
Or IsNull(sPassword) Then
Err.Raise 100, WScript.ScriptName, "/u:<username> /p:<password> required"
'WScript.Quit 100
End If
sDrive = ConnectDrive(sShare,sUsername,sPassword)
If IsNull(sDrive) Then
Err.Raise 200, WScript.ScriptName, "ConnectDrive failed..."
'WScript.Quit 200
End If
'
'
'...do your stuff...
'
'
'
DisconnectDrive sDrive
WScript.Quit 0
Function ConnectDrive(argShare,argUsername,argPassword)
ConnectDrive = Null
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Dim net : Set net = CreateObject("WScript.network")
Dim sDrive : sDrive = FreeDrive()
On Error Resume Next
net.MapNetworkDrive sDrive, sShare, False, argUsername, argPassword
If Err Then Exit Function
ConnectDrive = sDrive
End Function
Function DisconnectDrive(argDrive)
Dim net : Set net = CreateObject("WScript.network")
On Error Resume Next
net.RemoveNetworkDrive argDrive, True
End Function
Function FreeDrive()
Dim i
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
For i = Asc("D") To Asc("Z")
If Not fso.DriveExists(Chr(i)) Then
FreeDrive = Chr(i) & ":"
Exit Function
End If
Next
End Function
--
torgeir
Microsoft MVP Scripting and WMI
Porsgrunn Norway
<snip>
>> The problem is that I want ALL the event logs dumped up to one file
>> share, not saved locally.
<snip>
>If you use Kerberos authentication instead, you should be able to access network
>resources, but to use Kerberos, you need AD and Win2k/WinXP computers.
<snip>
Sounds reasonable. I haven't looked at all the samples and URLs you
sent, but I do have one question before I proceed... If I do set it
to use Kerberos (which isn't a problem, since this is specifically for
W2k servers), is the setting persistent, or is it per instance?
If it's per instance, I'm fine. If it's persistent and it is then
telling WMI to always user Kerberos, that's probably going to break
several otehr scripts and possibly some apps as well.
Thanks for the assistance. If you can answer the above, I'll start
redoing it with Kerberos authentication and let you know what I get.
:)
--Jonathan
Hi
It is per instance :-)
<snip>
>> Sounds reasonable. I haven't looked at all the samples and URLs you
>> sent, but I do have one question before I proceed... If I do set it
>> to use Kerberos (which isn't a problem, since this is specifically for
>> W2k servers), is the setting persistent, or is it per instance?
<snip>
>Hi
>
>It is per instance :-)
Cool. Then I'll see if I can find time to tackle that today and will
post a finished version for everyone's enjoyment (amusement?) when
done. Thanks again.
--Jonathan
In short, I haven't gotten very far. The code is down at the bottom.
Essentially, I think I'm missing something rather important... I set
the authorization and connection parameters to use Kerberos, which
seems to work fine. However, I'm accustomed to using something along
the lines of:
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
But, since I've already set the impersonation and connection with the
kerberos stuff, I didn't think I would need to do this. I assumed
that the objConnection would replace the objWMIService. But, when
trying to treat the objConnection as objWMIService using the ExecQuery
(method?), I get a security error: "SWbemServiceEx: A security
package specific error occurred". This indicated to me that I made
some assumptions somewhere that are just flat-out wrong. :)
So what did I mess up here? Do I still need my objWMIService, and if
so, how do I use one without declaring my impersonation again, since
I've already done that with Kerberos?
As a side note, if anyone wants to fix and repost the code below,
please just fix what is neccesary to get it to work... I'll add error
checking once I get it working, but it helps me to understand what's
going on if I can concentrate on just what I'm doing wrong before I
start adding in the extra parts to make it play nice (but I do
appreciate the previous error checking that was added to my last
script - it's probably going to become the basis for all my error
checking code). :)
--Jonathan
---------------------------------------
'Begin Script
Const wbemImpersonationLevelDelegate = 4
Const ForReading = 1
'Set Computer Names:
'Server to store event logs on:
Const FileDepot = "myserver"
'Logon account and domain:
Const AuthUser = "mydomain\admin"
'Logon password:
Const AuthPass = "passwordhere"
'Start Get Date
dtmThisDay = Day(Date)
dtmThisMonth = Month(Date)
dtmThisYear = Year(Date)
strBackupName = dtmThisYear & "_" & dtmThisMonth _
& "_" & dtmThisDay
'Start file open and read in servers
'Add servers to collection objDictionary
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("c:\scripts\servers.txt",_
ForReading)
i = 0
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
objDictionary.Add i, strNextLine
i = i + 1
Loop
For Each objItem in objDictionary
strComputer = objDictionary.Item(objItem)
Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objConnection = objwbemLocator.ConnectServer _
(strComputer, "root\cimv2", AuthUser, _
AuthPass, , "kerberos:" & strComputer)
objConnection.Security_.ImpersonationLevel _
= wbemImpersonationLevelDelegate
Set colLogFiles = objConnection.ExecQuery ("Select * from _
Win32_NTEventLogFile where LogFileName='Application'")
For Each objLogfile in colLogFiles
objLogFile.BackupEventLog("\\" & FileDepot _
& "\EventLogs\" & strBackupName & "_" _
& strComputer & "_app.evt")
' objLogFile.ClearEventLog()
Next
Next
For your problem, Instead of using kerberos, n much easier alternative
method will be just save the event logs to the local machine, after that,
you can use your script to copy the log file to a centralized position.
Since the file copying process is initialized from your script (I assume
you run the script interactive with a domain admin login), there is no
delegation needed.
Regards,
Gang Guo
This posting is provided "AS IS" with no warranties, and confers no rights.
Got .Net? http://www.gotdotnet.com