widsnet.com
6Oct/110

Copy security rights between sites

Set the security rights for a person or group on one site manually, then use this script to copy the same rights to other sites.
Must ofcourse be run as a user with proper privilegies.

Const ForAppending = 8

Set colArgsNamed = WScript.Arguments.Named
If colArgsNamed.Exists("User") And colArgsNamed.Exists("SMSFromServer") And colArgsNamed.Exists("SMSToServer") Then
	strUser = colArgsNamed.Item("User")
	strFromSiteServer = colArgsNamed.Item("SMSFromServer")
	strToSiteServer = colArgsNamed.Item("SMSToServer")
Else
	WScript.Echo "Usage: cscript " & WScript.ScriptName & " /User:<UserName>"
	WScript.Echo vbTab & "/SMSFromServer:<FromServer> /SMSToServer:<ToServer>"
	WScript.Echo "Optional: /Copy"
	WScript.Echo ""
	WScript.Echo vbTab & "<User> is the domain\user that need rights on <ToServer>"
	WScript.Echo vbTab & "<FromServer> is the SMS Server to get the rights from"
	WScript.Echo vbTab & "<ToServer> is the SMS Server to set the rights to"
	WScript.Echo vbTab & "/Copy to set the rights. Otherwise only a compare will be done!"
	WScript.Quit
End If

Set oFSO = CreateObject("scripting.filesystemobject")
Set oLogFile = oFSO.OpenTextFile(Replace(WScript.ScriptFullName, "vbs", "log"), ForAppending, True)
logThis "Logfile: " & Replace(WScript.ScriptFullName, "vbs", "log"), True

If colArgsNamed.Exists("Copy") Then
	logThis "Copying permissions for user '" & strUser & "'",True
Else
	logThis "Checking permissions for user '" & strUser & "'",True
End If
logThis "From: " & strFromSiteServer & " To: " & strToSiteServer, True
logThis "", True

Set objFromServerConnection = getSiteConnection(strFromSiteServer)
Set objToServerConnection = getSiteConnection(strToSiteServer) 

Set colFromItems = objFromServerConnection.ExecQuery("SELECT * FROM SMS_UserClassPermissions WHERE UserName='" & Replace(strUser, "\", "\\") & "'")
If colFromItems.Count > 0 Then
	For Each objFromItem in colFromItems
		bolMatch = False
		intToPermissions = 0
		intFromObjectKey = objFromItem.ObjectKey
		intFromPermissions = objFromItem.ClassPermissions
		logThis strFromSiteServer & ": ObjectKey: " & intFromObjectKey & " Permission: " & intFromPermissions, False
		logThis strFromSiteServer & ": " & getStrObjectKey(intFromObjectKey) & ": " & getStrPermission(intFromPermissions), False
		Set colToItems = objToServerConnection.ExecQuery("SELECT * FROM SMS_UserClassPermissions WHERE UserName='" & Replace(strUser, "\", "\\") & "' And ObjectKey='" & intFromObjectKey & "'")
		If colToItems.Count > 0 Then
			For Each objToItem In colToItems
				intToObjectKey = objToItem.ObjectKey
				intToPermissions = objToItem.ClassPermissions
				If intFromPermissions = intToPermissions Then
					logThis "Permissions match for: " & getStrObjectKey(intFromObjectKey), True
					bolMatch = True
				Else
					logThis strToSiteServer & ": ObjectKey: " & intToObjectKey & " Permission: " & intToPermissions, False
					logThis strToSiteServer & ": " & getStrObjectKey(intToObjectKey) & ": " & getStrPermission(intToPermissions), False
				End If
			Next			
		End If
		If Not bolMatch Then
			logThis "Permissions don't match for: " & getStrObjectKey(intFromObjectKey), True
			If intToPermissions  = 0 Then
				logThis "Difference: " & getStrPermission(intFromPermissions), True
			Else
				logThis "Difference: " & getStrPermission(intFromPermissions - (intFromPermissions And IntToPermissions)), True
			End If
			If colArgsNamed.Exists("Copy") Then
				SetPermissions objToServerConnection, strUser, intFromObjectKey, intFromPermissions
			End If
		End if
	Next
End If

Function getSiteConnection(strServer)
	Set objLocator = CreateObject("WbemScripting.SWbemLocator")
	Set objConnection = objLocator.ConnectServer(strServer, "root\sms")
	Set colItems = objConnection.ExecQuery("SELECT * FROM SMS_ProviderLocation")
	For Each objItem in colItems
		strSitecode = objItem.SiteCode
	Next
	
	Set objConnection = objLocator.ConnectServer(strServer, "root\sms\site_" & strSitecode)
	Set getSiteConnection = objConnection
End Function

Sub SetPermissions(objConnection, strUser, intObjectKey, intPermissions)
	logThis "Changing permissions", True
    Set objPermissions = objConnection.Get("SMS_UserClassPermissions").SpawnInstance_()
    If Err.Number <> 0 Then
        logThis "Couldn't get class permissions object", True
        Exit Sub
    End If
    
    objPermissions.UserName = strUser
    objPermissions.ObjectKey = intObjectKey
    objPermissions.ClassPermissions = intPermissions
    
    objPermissions.Put_
    If Err.Number <> 0 Then
        logThis "Couldn't set class permissions!", True
        Err.Clear
    End If
End Sub
 
Function getStrPermission(intPermission)
	If intPermission And 1 Then strPermission = "READ"
	If intPermission And 2 Then strPermission = strPermission & ", MODIFY"
	If intPermission And 4 Then strPermission = strPermission & ", DELETE"
	If intPermission And 8 Then strPermission = strPermission & ", DISTRIBUTE"
	If intPermission And 16 Then strPermission = strPermission & ", Not used"
	If intPermission And 32 Then strPermission = strPermission & ", REMOTE_CONTROL"
	If intPermission And 64 Then strPermission = strPermission & ", ADVERTISE"
	If intPermission And 128 Then strPermission = strPermission & ", MODIFY_RESOURCE"
	If intPermission And 256 Then strPermission = strPermission & ", ADMINISTER"
	If intPermission And 512 Then strPermission = strPermission & ", DELETE_RESOURCE"
	If intPermission And 1024 Then strPermission = strPermission & ", CREATE"
	If intPermission And 2048 Then strPermission = strPermission & ", VIEW_COLL_FILE"
	If intPermission And 4096 Then strPermission = strPermission & ", READ_RESOURCE"
	If intPermission And 8192 Then strPermission = strPermission & ", DELEGATE"
	If intPermission And 16384 Then strPermission = strPermission & ", METER"
	If intPermission And 32768 Then strPermission = strPermission & ", MANAGESQLCOMMAND"
	If intPermission And 65536 Then strPermission = strPermission & ", MANAGESTATUSFILTER"
	If intPermission And 131072 Then strPermission = strPermission & ", MANAGEFOLDER"
	If intPermission And 262144 Then strPermission = strPermission & ", NETWORKACCESS"
	If intPermission And 524288 Then strPermission = strPermission & ", IMPORTMACHINE"
	If intPermission And 1048576 Then strPermission = strPermission & ", CREATETSMEDIA"
	If intPermission And 2097152 Then strPermission = strPermission & ", MODIFYCOLLECTIONSETTING"
	If intPermission And 4194304 Then strPermission = strPermission & ", MANAGEOSDCERTIFICATE"
	If intPermission And 8388608 Then strPermission = strPermission & ", RECOVERUSERSTATE"
	getStrPermission = strPermission
End Function

Function getStrObjectKey(intObjectKey)
	Select Case intObjectKey
		Case 1: strObjectKey = "SMS_Collection" 
		Case 2: strObjectKey = "SMS_Package" 
		Case 3: strObjectKey = "SMS_Advertisement" 
		Case 4: strObjectKey = "SMS_StatusMessage" 
		Case 5: strObjectKey = "Not used"
		Case 6: strObjectKey = "SMS_Site" 
		Case 7: strObjectKey = "SMS_Query" 
		Case 8: strObjectKey = "SMS_Report" 
		Case 9: strObjectKey = "SMS_MeteredProductRule" 
		Case 10: strObjectKey = "SMS_ApplicableUpdatesSummaryEx" 
		Case 11: strObjectKey = "SMS_ConfigurationItem" 
		Case 14: strObjectKey = "SMS_OperatingSystemInstallPackage" 
		Case 15: strObjectKey = "SMS_Template" 
		Case 16: strObjectKey = "SMS_UpdatesAssignment" 
		Case 17: strObjectKey = "SMS_StateMigration" 
		Case 18: strObjectKey = "SMS_ImagePackage" 
		Case 19: strObjectKey = "SMS_BootImagePackage" 
		Case 20: strObjectKey = "SMS_TaskSequencePackage" 
		Case 21: strObjectKey = "SMS_DeviceSettingPackage" 
		Case 22: strObjectKey = "SMS_DeviceSettingItem"
		Case 23: strObjectKey = "SMS_DriverPackage" 
		Case 24: strObjectKey = "SMS_SoftwareUpdatesPackage" 
		Case 25: strObjectKey = "SMS_Driver"
		Case Else: strObjectKey = intObjectKey
	End Select
	getStrObjectKey = strObjectKey
End Function

Sub logThis(strText, bolOutputToScreen)
	oLogFile.WriteLine(strText)
	If bolOutputToScreen Then WScript.Echo strText
End Sub
24Aug/110

vbs named arguments and extending an array

Update to previous posts (http://widsnet.com/2011/07/set-binary-delta-replication-on-packages) (http://widsnet.com/2011/06/update-distribution-points-on-a-schedule-vbscript) to be able to take input from the commandline and collection IDs from a file.

Const ForReading = 1
Const STORAGE_DIRECT = 2
Const AP_USE_BINARY_DELTA_REP = &amp;H04000000

Set colArgsNamed = WScript.Arguments.Named
If colArgsNamed.Exists("File") And colArgsNamed.Exists("SMSServer") And colArgsNamed.Exists("SMSSite") Then
	arrPackageID = getArrayFromFile(colArgsNamed.Item("File"))
	strSMSServer = colArgsNamed.Item("SMSServer")
	strSMSSiteCode = colArgsNamed.Item("SMSSite")
Else
	WScript.Echo "Usage: cscript " & WScript.ScriptName & " /File:<FileName> /SMSServer:<Server>"
	WScript.Echo vbTab & "/SMSSite:<SiteCode>"
	WScript.Echo "Optional arguments: /UpdateDay:<YYYY-MM-DD> /UpdateTime:<HH:MM> /DeltaRep"
	WScript.Echo ""
	WScript.Echo vbTab & "<Server> is the SMS Server to connect to"
	WScript.Echo vbTab & "<SiteCode> is the SMS Site to connect to"
	WScript.Echo vbTab & "<FileName> is a text file with one CollectionID per row"
	WScript.Echo vbTab & "<YYYY-MM-DD> is the date to redistribute the package"
	WScript.Echo vbTab & "<HH:MM> is the time to redistribute the package"
	WScript.Echo vbTab & "/DeltaRep to enable Binary Delta Replication"
	WScript.QuitEnd If
Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSMSConnection = objLocator.ConnectServer(strSMSServer, "root\sms\site_" &amp; strSMSSiteCode)

If colArgsNamed.Exists("UpdateDay") And colArgsNamed.Exists("UpdateTime") Then
	strUpdateDay = colArgsNamed.Item("UpdateDay")
	strUpdateTime = colArgsNamed.Item("UpdateTime")
	strWMIDate = replace(strUpdateDay, "-", "") &amp; Replace(strUpdateTime, ":", "") &amp; "00.000000+***"
	WScript.Echo "Date and Time: " &amp; strUpdateDay &amp; " " &amp; strUpdateTime
	bUpdateDPsched = True
Else
	bUpdateDPsched = False
End If

'
For Each strPackageID In arrPackageID
	If bUpdateDPSched Then
		setNonRecurringUpdateSchedule objSMSConnection, strPackageID, strWMIDate
	End If
	If colArgsNamed.Exists("DeltaRep") Then
		setBinaryDeltaReplication objSMSConnection, strPackageID
	End If
Next

'
Function getArrayFromFile(strFile)
	Dim arr()
	Set objFSO = CreateObject("Scripting.FileSystemObject")
	If objFSO.FileExists(strFile) Then
		Set objFile = objFSO.OpenTextFile(strFile, ForReading, True)
		i = 0
		Do While Not objFile.AtEndOfStream
			strText = Trim(objFile.ReadLine)
			strText = Replace(strText, Chr(160), "")
			If strText &lt;&gt; "" Then
				ReDim Preserve arr(i+1)
				arr(i) = strText
				i = i+1
			End If
		Loop
		objFile.Close
	End If
	getArrayFromFile = arr
End Function
4Jul/110

Set Binary Delta Replication on Packages

A follow-up post to http://widsnet.com/2011/06/update-distribution-points-on-a-schedule-vbscript/
Some packages didn't have the "Enable binary differential replication" checkbox enabled. That lead to a lot of unnecessary network traffic. So to avoid that this "add-on" script enables binary delta replication.

Const AP_USE_BINARY_DELTA_REP = &H04000000

setBinaryDeltaReplication objSMSConnection, strPackageID

Sub setBinaryDeltaReplication(objSMSConnection, strPackageID)
	Set colPkg = objSMSConnection.ExecQuery("Select * from SMS_Package where PackageID='" & strPackageID & "'")
	If colPkg.Count = 1 Then
		Set objPackage = objSMSConnection.Get("SMS_Package.PackageID='" & strPackageID & "'")
		If Not objPackage.PkgFlags And AP_USE_BINARY_DELTA_REP Then
			objPackage.PkgFlags = objPackage.PkgFlags OR AP_USE_BINARY_DELTA_REP
			objPackage.Put_
		End If
		If objPackage.PkgFlags And AP_USE_BINARY_DELTA_REP Then
			WScript.Echo strPackageID & " Delta Replication: Enabled"
		Else
			WScript.Echo strPackageID & " Delta Replication: Disabled!"
		End If
	End If
End Sub
30Jun/110

Update distribution points on a schedule vbscript

A script to set a "Update distribution point on a schedule" on several PackageIDs to a single non recurring date and time. Doing like this to avoid distributing production packages under working hours. And scripting it since I need to update around 150 packages.

Const STORAGE_DIRECT = 2

strSMSServer = "server"
strSMSSiteCode = "CEN"
arrPackageID = Array("CEN00001", "CEN00002", "CEN00003")
strUpdateDay = "2011-07-01"
strUpdateTime = "01:00"
strWMIDate = replace(strUpdateDay, "-", "") & Replace(strUpdateTime, ":", "") & "00.000000+***"

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSMSConnection = objLocator.ConnectServer(strSMSServer, "root\sms\site_" & strSMSSiteCode)
WScript.Echo "Date and Time: " & strUpdateDay & " " & strUpdateTime
For Each strPackageID In arrPackageID
	setNonRecurringUpdateSchedule objSMSConnection, strPackageID, strWMIDate
Next

Sub setNonRecurringUpdateSchedule(objSMSConnection, strPackageID, strWMIDate)
	Set Token = objSMSConnection.Get("SMS_ST_NonRecurring")
	Token.DayDuration = 0
	Token.HourDuration = 0
	Token.MinuteDuration = 0
	Token.IsGMT = 0
	Token.StartTime = strWMIDate

	setUpdateSchedule objSMSConnection, strPackageID, Token
End Sub

Sub setUpdateSchedule(objSMSConnection, strPackageID, Token)
	Set colPkg = objSMSConnection.ExecQuery("Select * from SMS_Package where PackageID='" & strPackageID & "'")
	If colPkg.Count = 1 Then
		Set objPackage = objSMSConnection.Get("SMS_Package.PackageID='" & strPackageID & "'")
		If objPackage.PkgSourceFlag = STORAGE_DIRECT Then
			objPackage.RefreshSchedule = Array(Token)
			objPackage.Put_
			WScript.Echo strPackageID & " Software Package updated"
		Else
			WScript.Echo strPackageID & " Software Package not using STORAGE_DIRECT!"
		End If
	Else
		Set colPkg = objSMSConnection.ExecQuery("Select * from SMS_DriverPackage where PackageID='" & strPackageID & "'")
		If colPkg.Count = 1 Then
			Set objPackage = objSMSConnection.Get("SMS_DriverPackage.PackageID='" & strPackageID & "'")
			If objPackage.PkgSourceFlag = STORAGE_DIRECT Then
				objPackage.RefreshSchedule = Array(Token)
				objPackage.Put_
				WScript.Echo strPackageID & " Driver Package updated"
			Else
				WScript.Echo strPackageID & " Software Package not using STORAGE_DIRECT!"
			End If
		Else
			WScript.Echo strPackageID & " Package not found!"
		End If
	End If
End Sub