VB script to retrieve Access Rights Reporting from Visual SVN - vbscript

While I'm working on SID conversion, I found the workable script with the VirsualSVN installed on the test machine, but the script was not working on the server. I saved file as test.vbs put on the desktop and use the following command to execute the code and produce the output as the text file: cscript test.vbs > c:\output.txt
On the test machine, I installed VisualSVN version 2.5.8 and root repositories is on C:\Repositories
While on the server, installed VisualSVN version 1.6.3 and root repositories is on E:\Repositories
From the script below, I'm lack in coding and no idea where should I modify the script to make it work on the server? I'm seeking your expert help on this.
'
' Print permissions in the form: user_name,path,level
'
strComputer = "."
Set wmi = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\VisualSVN")
Set win = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
' Return text representation for the Access Level
Function AccessLevelToText(level)
If level = 0 Then
AccessLevelToText = "No Access"
ElseIf level = 1 Then
AccessLevelToText = "Read Only"
ElseIf level = 2 Then
AccessLevelToText = "Read/Write"
Else
AccessLevelToText = "Unknown"
End If
End Function
' Return repository path for the object
Function GetPath(obj)
cname = assoc.Path_.Class
If cname = "VisualSVN_Service" Then
GetPath = "Repositories Root"
ElseIf cname = "VisualSVN_Repository" Then
GetPath = assoc.Name
ElseIf cname = "VisualSVN_RepositoryEntry" Then
GetPath = assoc.RepositoryName & ": " & assoc.Path
Else
GetPath = "Unknown"
End If
End Function
' Convert SID to user name
Function SidToUserName(sid)
Set account = win.Get("Win32_SID.SID='" & sid & "'")
user = account.AccountName
domain = account.ReferencedDomainName
SidToUserName = domain & "\" & user
End Function
' Iterate over all security descriptions
Set objs = wmi.ExecQuery("SELECT * FROM VisualSVN_SecurityDescriptor")
For Each obj In objs
Set assoc = wmi.Get(obj.AssociatedObject)
For Each perm in obj.Permissions
sid = perm.Account.SID
level = AccessLevelToText(perm.AccessLevel)
Wscript.Echo SidToUserName(sid) & "," & GetPath(assoc) & "," & level
Next
Next
Code reference from http://www.svnforum.org/threads/38790-Access-Rights-Reporting-in-Subversion-or-Viusal-SVN

0x8004100e means that the namespace (/root/VisualSVN) doesn't exist. Perhaps the version installed on the server is too old and doesn't create this namespace in WMI.

Following #Ansgar's answer.
VisualSVN Server versions older than 2.0 can't be managed via WMI.

Related

Active Directory running user creation VBS outside of server doesnt grant groupmembership

my problem is:
when i run my user creation script at my server, it works fine, a user gets created and has a membership (according to a .txt file)
when i run that same script outside of my server, the user gets created but doesnt have memberships
when i run that same script as admin outside of my server, the user gets created but doesnt have memberships
so this is the relevant code that adds memberships:
Dim fso, f, Row, Field
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile ("\\some\folder\user.txt",1,0)
Do while not f.AtEndOfLine
Row = f.readLine
Field = split(Row,",")
Username = Field(0)
Group = Field(1)
Lastname = Field(2)
Password = Field(3)
ScriptP = Field(4)
Project = Field(5)
Call UserCreation(Username,Group,Lastname,Password,ScriptP)
Loop
f.Close
Wscript.Quit(0)
Sub UserCreation (Username,Group,Lastname,Password,ScriptP)
Dim ouo, b
Set ouo = GetObject("LDAP://OU=abcOU,DC=my,DC=domain")
Set b = ouo.Create("user", "CN=" & Group & " " & Lastname)
Dim WshShell, ret
Set WshShell = WScript.CreateObject("WScript.Shell")
b.Put "sAMAccountName", Username
b.Put "userPrincipalName", Username & "#my.domain"
b.Put "scriptPath", ScriptP
b.SetInfo
b.SetPassword Password
b.AccountDisabled = False
b.SetInfo
cmdbegin = "cmd /C dsmod group"
CN = "CN=TN_" & Project & ",OU=projectOU,DC=my,DC=domain"
oudc = "OU=abcOU,DC=my,DC=domain"
cmdmid = "-addmbr"
grpadd = cmdbegin & " " & AddQuotes(CN) & " " & cmdmid & " " & AddQuotes("CN=" & Group & " " & Lastname & "," & oudc) & " >>\\some\folder\log.txt"
WshShell.Run grpadd
that log.txt just adds a row like this at completion:
dsmod was successful:CN=TN_Test,OU=projectOU,DC=my,DC=domain
The root of the problem is likely that dsmod is not installed on the computer you're running this from, since the documentation says that it is only installed by default on domain controllers. That can be confirmed by just running dsmod from the command line.
But that also seems like the hard way to do it. You can replace everything from the cmdbegin line to the end with this:
Set group = GetObject("LDAP://CN=TN_" & Project & ",OU=projectOU,DC=my,DC=domain")
group.Add(b.aDSPath)
The group variable will be a IADsGroup object, so you can use its Add method to add the user.

how to create Variable registry path in vb script

I want help to create a registry path which will use a variable for logged in user SID. The path is like - HKEY_USERS\'%UserSID%'\Software\Microsoft\Office\16.0\Outlook
User SID should be picked for whoever user is currently logged in on the system.
I don't know how to create this variable?
I want to use this variable in my script array.
KEY_PATHS = Array("HKEY_USERS\S-1-5-21-4054882774-118064744-2143271696-500\Software\Microsoft\Office\16.0\Outlook", _
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-2660683129-3636505375-3381148637-65620")
DEBUG_PRINTING = False
MASTER_EXECUTION
Sub MASTER_EXECUTION()
' WMI Class Management
MAINTAIN_WMI_CLASS()
' Registry Key Storage
For Each KEY_PATH In KEY_PATHS
STORE_KEYS(KEY_PATH)
Next
If Err.Number <> 0 Then
EVENT_WRITER "ERROR","Storing Registry Keys Failed " & Err.Number & " | " & Err.Description
Else
EVENT_WRITER "INFO", "Storing Registry Keys Completed Successfully"
End If
End Sub
Function CONVERT_HIVE(HIVE)
' Check and return a system name based on a friendly name
If UCase(HIVE) = "HKEY_LOCAL_MACHINE" Then
CONVERT_HIVE = &H80000002
ElseIf UCase(HIVE) = "HKEY_USERS" Then
CONVERT_HIVE = &H80000002
ElseIf UCase(HIVE) = "HKEY_CURRENT_CONFIG" Then
CONVERT_HIVE = &H80000005
Else
EVENT_WRITER "ERROR","Converting Hive " & HIVE & " failed - " & Err.Number & " | " & Err.Description
WScript.Quit
End If
End Function
I got my answer in one of Microsoft thread:
Below VB code will fetch logged in user sid and and we can use that variable for our purpose:
vbs code in image
'And the variable path i was looking for will be like
KEY_PATHS = Array("HKEY_USERS\" & Sid & "\Software\Microsoft\Office\16.0\Outlook\PST")

Run BAT file on remote server using VBScript. No psexec, and as a different user

I'm trying to execute a a BAT file on a remote server using VBScript. Further requirements:
psexec is not allowed
I need the script to operate under the permissions of another user, not those of my own workstation
I have consulted this article: https://learn.microsoft.com/en-us/windows/desktop/WmiSdk/connecting-to-wmi-remotely-with-vbscript
I see how creating the connection works, but I can't figure out how to then create a process using that same connection.
I believe this solution is really close, the only problem is I think it impersonates the user of the computer it is currently running on:
strCommand = "C:\temp\copyall.bat"
strPath = "C:\temp"
strcomputer="."
process = "winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2"
msgbox process
Set objWMIService = GetObject(process)
Set objProcess = objWMIService.Get("Win32_Process")
errReturn = objProcess.Create(strCommand, strPath, Null, intProcessID)
If errReturn = 0 Then
WScript.Echo "scan success: " & intProcessID
Else
WScript.Echo "scan fail: " & errReturn
End If
This example from Microsoft's site shows how to create the connection properly but I don't know how to then use that connection.
' Full Computer Name
' can be found by right-clicking My Computer,
' then click Properties, then click the Computer Name tab)
' or use the computer's IP address
strComputer = "FullComputerName"
strDomain = "DOMAIN"
Wscript.StdOut.Write "Please enter your user name:"
strUser = Wscript.StdIn.ReadLine
Set objPassword = CreateObject("ScriptPW.Password")
Wscript.StdOut.Write "Please enter your password:"
strPassword = objPassword.GetPassword()
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, _
"Root\CIMv2", _
strUser, _
strPassword, _
"MS_409", _
"ntlmdomain:" + strDomain)
Set colSwbemObjectSet = objSWbemServices.ExecQuery("Select * From Win32_Process")
For Each objProcess in colSWbemObjectSet
Wscript.Echo "Process Name: " & objProcess.Name
Next
The answer is probably staring me in the face but I just can't see it right now. Ideas?
After connecting to the remote server simply get the Win32_Process object and call the Create() method like you'd do locally.
Set objSWbemServices = objSWbemLocator.ConnectServer(...)
Set objProcess = objSWbemServices.Get("Win32_Process")
errReturn = objProcess.Create(strCommand, strPath, Null, intProcessID)
The file you want to run must exist locally on the remote server for this to work.
Also note that this normally requires admin privileges on the remote system.

Getting Win32_Service security descriptor using VBScript

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.)

How to change file permissions with WMI?

I'm want to do the equivalent of what is described here from a script. Basically, I want to take ownership of the file, and set the permissions to OWNER/Full Control.
It seems to me that using WMI from a vbs script is the most portable way. That is, I'd like to avoid xcacls, icacls and other tools that either require a download, or are supported only on some versions of windows.
After googling around, I found this code for taking ownership:
'connect to WMI namespace on local machine
Set objServices =
GetObject("winmgmts:{impersonationLevel=impersonate}")
'get a reference to data file
strFile = Wscript.Arguments(0)
Set objFile = objServices.Get("CIM_DataFile.Name='" & strFile & "'")
If objFile.TakeOwnership = 0 Then
Wscript.Echo "File ownership successfully changed"
Else
Wscript.Echo "File ownership transfer operation"
End If
The pieces I'm still missing is setting the permissions, and having it work on relative paths.
Since you're already using TakeOwnership in the CIM_DataFile class, I'd assume you could just use ChangeSecurityPermissions to change the permissions, which is in the same class.
And you might be able to use GetAbsolutePathName to convert your relative paths to absolute paths before you use them.
Taking the hints from ho1's answer, I googled around some more, and eventually came up with this:
This script finds the current user SID, then takes ownership and changes the permissions on the file given in argv[0] to Full Control only to current user.
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}")
Function GetCurrentUserSID
' Get user name '
Set colComputer = objWMI.ExecQuery("Select * from Win32_ComputerSystem")
' Looping over one item '
For Each objComputer in colComputer
currentUserName = objComputer.UserName
Next
Set AccountSIDs = GetObject("Winmgmts:").InstancesOf("Win32_AccountSID")
For Each AccountSID In AccountSIDs
AccountKey = AccountSID.Element
Set objAccount = GetObject("Winmgmts:"+AccountKey)
strName = objAccount.Domain & "\" & objAccount.Name
If strName = currentUserName Then ' that's it
SIDKey = AccountSID.Setting
Set SID = GetObject("Winmgmts:" + SIDKey)
GetCurrentUserSID = SID.BinaryRepresentation
Exit For
End If
Next
End Function
Function LimitPermissions(path, SID)
Set objFile = objWMI.Get("CIM_DataFile.Name='" & path & "'")
Set Trustee = GetObject("Winmgmts:Win32_Trustee").SpawnInstance_
Trustee.SID = SID
Set ACE = getObject("Winmgmts:Win32_Ace").Spawninstance_
ACE.AccessMask = 2032127 ' Full Control
ACE.AceFlags = 3
ACE.AceType = 0
ACE.Trustee = Trustee
Set objSecDescriptor = GetObject("Winmgmts:Win32_SecurityDescriptor").SpawnInstance_
objSecDescriptor.DACL = Array(ACE)
objFile.ChangeSecurityPermissions objSecDescriptor, 4
End Function
Function TakeOwnership(path)
Set objFile = objWMI.Get("CIM_DataFile.Name='" & path & "'")
TakeOwnership = objFile.TakeOwnership
End Function
' Main '
strFilename = Wscript.Arguments(0)
Set fso = CreateObject("Scripting.FileSystemObject")
path = fso.GetAbsolutePathName(strFilename)
SID = GetCurrentUserSID
TakeOwnership path
LimitPermissions path, SID

Resources