Sunday, September 25, 2005

Granting access to eventlogs on Windows Server 2003

When Windows Server 2003 came out, a more flexible method for granting access to eventlogs was made available. A REG_SZ called CustomSD below HKLM\System\CCS\Services\Eventlog\NameOfLog contains an SDDL string with the specified access. This can be automated using the suggested Group Policy changes or you can use a script like the one below. This script attempts to find a local admin for a given AD site and grant this person and a global Security Reviewer role read access to the server at hand. This script could be used as a startup script on the servers, you want to delegate access to.

The WSF script -

<job>
<script language="vbscript">
Option explicit

main

sub main

dim strLocalAdminSid
dim strSecurityReviewerSid

strLocalAdminSid = GetSidForGroup("Local Admin for " & GetSite)
strSecurityReviewerSid = GetSidForGroup("Security Reviewer Role")

UpdateEventlogAccess strLocalAdminSid
UpdateEventlogAccess strSecurityReviewerSid

end sub

sub UpdateEventlogAccess(strSID)
' Give user read access to eventlog
const ROOTKEY="HKLM\SYSTEM\CurrentControlSet\Services\Eventlog"
dim objShell
dim strSDDLKey
dim strSDDL
dim strReadAccessSDDL
const NOSUCHKEY=&h80070002
dim objEventLog
dim lngError
set objShell = CreateObject("wscript.shell")
for each objEventlog in GetObject("winmgmts:")._
        InstancesOf("win32_NTeventlogFile")
    wscript.echo objEventlog.Logfilename
    strSDDLKey=ROOTKEY & "\" & _
            objEventlog.Logfilename & "\CustomSD"
    on error resume next
    strSDDL=objShell.RegRead(strSDDLKey)
    lngError=err
    on error goto 0
    if lngError<>0 then
        ' Key not found - so we can’t do anything
    else
        wscript.echo "Existing SDDL - " & strSDDL
        ' check if key needs to be updated
        strReadAccessSDDL = "(A;;0x01;;;" & strSID & ")"
        if instr(strSDDL,strReadAccessSDDL)=0 then
            strSDDL=strSDDL & strReadAccessSDDL
            objShell.RegWrite strSDDLKey, strSDDL, "REG_SZ"
            wscript.echo "New SDDL - " & strSDDL
        end if
    end if
next

end sub

function GetSite
dim objInfo
set objInfo = CreateObject("ADSystemInfo")
GetSite = objInfo.SiteName
end function

function GetSidForGroup(strName)
dim objWMIService
dim objItems
dim objItem
dim strSID
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set objItems = objWMIService.ExecQuery _
    ("Select * from Win32_Group Where name='" & strName & "'")
For Each objItem in objItems
    strSID = objItem.SID
Next
GetSidForGroup=strSID
end function
</script>
</job>

Use it at your own risk - but have fun!

1 comment:

PowerAxl said...

Thanks for this one - soon we shall be Domain Admin free!