1 Reply Latest reply on May 18, 2011 1:56 PM by Josh Lentz
      • 1. Channel Security Discussion - April2011

        Sorry about the delay on getting this out here....


        The following steps detail how you can use the Delay File Download option in a package to validate that the machine is in the correct AD group prior to installing channel content.  This is just one of the ways you can use this option to perform checks to make sure that license compliance requirements are adheared to.


        In the package select the delay download of files until pre scripts have run.



        You can either include the vb script in the scripts directory of the channel or pre deliver the script to all machines using a subsequent channel (which is what we do).  All scripts and application we use in deployments are delivered to a deployment utilities folder for use with any channel.


        The script can then be called using the pre install or pre update events in the Customization tab.  The script accetps one argument, which will be the AD group you want to check for membership. 


        The script will then return a 0 if the machine is in the group you specified and a 1 if it is not.  If there is no match (return 1) the channel will go into a failed(pre-install) or failed(pre-update) state and will attempt to install again next time subscriptions is run.  If there is a match (return 0) the channel installation will carry on.


        Note:  When calling vb scripts you will need to past the script to the wscript.exe engine.




        The following is the vbs that you will need to alter slightly for you specific environment.  You will at least need to put in the LDAP connection string information.  This should be a specific server so you do not have to wait for AD replication, but can also be set to the root domain.


        On the return code of 1 you can also choose to send an email to support if you choose.  This code has not been included for simplicity.


        Dim strpath
        Dim strComputerGroups
        Dim strADGroupName
        Dim strLogFile
        Dim strComputerName
        Dim strADConnectionString
        Dim sCurPath
        Dim objfso
        Dim intReturnValue

        'Set the filesystem object used for logging
        Set objfso=CreateObject("Scripting.FileSystemObject")

        'get the current path for the log file location
        sCurPath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".")

        'set the log file variable with the current path
        strLogFile = sCurPath & "\ADGroupMembershipCheck.txt"

        'set the connection string
        strADConnectionString="dc=<domain name>,dc=com" 'Add you AD root here (example: dc=childdomain,dc=domainname,dc=com"

        'set the return value to 1 so the package will fail installation "failed(pre-install)" or
        'update "failed(pre-update)" unless it is in the specified AD group.
        intReturnValue = 1


        'Get the computer name so it can be use in the LADP query to determin group membershipPrivate Sub GetComputerName()

        On Error Resume Next

        Call LogResults("GetComputerName()", "Getting the computer name...")

        Dim wshnetwork

        Set wshnetwork=CreateObject("Wscript.Network")

        Call LogResults("GetComputerName()", "Computer name:  " & strComputerName)

        If Err Then Call ErrorReport("GetComputerName")

        End Sub


        'Get the argument <AD group name> from the command line.
        'Example:  C:\Windows\System32\wscript.exe ADGroupMembershipCheck.vbs <AD group name>
        Private Sub GetArguments()

        On Error Resume Next

        Call LogResults("GetArguments()", "Getting Arguments...")

        Dim argumentsCount
        Dim CheckArgument
        Dim Argument

        argumentsCount = wscript.arguments.count
        Call LogResults("GetArguments()", "Number of arguments:  " & argumentsCount)

        if argumentsCount = 1 Then

          Argument = (Trim(wscript.Arguments(0)))
          If Argument ="" Then
           Call LogResults("GetArguments()", "Argument text:  " & Argument & ".  Ending Script")
           Call EndScript
           strADGroupName = Trim(Argument)
           Call LogResults("GetArguments()", "Argument text:  " & strADGroupName)
          End If
        End If
        If Err <> 0 then call ErrorReport("GetArguments")

        End Sub

        Private Function GetComputerOU
          On Error Resume Next

        Call LogResults("GetComputerOU", "Getting the computer OU.")

                Dim adoConn, adoRS

                Set adoConn = CreateObject("ADODB.Connection")
                adoConn.Provider = "ADSDSOObject"
                'adoConn.Properties("User ID") = ""
                'adoConn.Properties("Password") = ""
                'adoConn.Properties("Encrypt Password") = False


                Set adoRS = adoConn.Execute("<LDAP://" & strADConnectionString & ">;" & _
                       "(&(objectclass=Computer)(cn=" & ComputerName & "));" & _
                       "operatingSystemServicePack, operatingsystem, distinguishedName;SubTree")
                Dim dn, strTRIMdn, strTRIMdn1, TrimmedDN
                dn = adoRS.fields.item("distinguishedName").value
                strTRIMdn = InStr(dn, ",strADConnectionString")
                strTRIMdn1 = InStr(dn, ",")
                TrimmedDN = Left(dn, strTRIMdn -1)
                strComputerOU = Mid(TrimmedDN, strTRIMdn1 + 1)
                    If Err.Number <> "0" Then

                        strComputerOU = "AD Account Missing"
                        Err.Number = "0"

                    End If


                Loop Until adoRS.EOF

                'adoConn = Nothing

        If Err Then Call ErrorReport("GetComputerOU")

            End Function


        'Get the AD Group and check it against the argument for a match.  If it matches return 0 and install the channel.
        Private Sub CheckADSubscriptions


        On Error Resume Next

        ' Query AD and show this machine's current AD subscritpions
        Call LogResults("CheckADSubscriptions()", "Getting AD Subscriptions...")
        'Create ADO Connection Object
        set adoConn = CreateObject("ADODB.Connection")
        adoConn.Provider = "ADSDSOObject"

        Call LogResults("CheckADSubscriptions()", "Connection string:  "& _
        "<LDAP://" & strADConnectionString & ">;" & _
                  "(&(objectClass=Computer)(cn=" & strComputerName & "));" & _

        'Get all subtree info from AD for defined Computer
        set adoRS = adoConn.Execute("<LDAP://" & strADConnectionString & ">;" & _
                  "(&(objectClass=Computer)(cn=" & strComputerName & "));" & _

        Do Until adoRS.eof

          CurrentGroups = adoRS.fields.item("MemberOf").value
          If IsNull(CurrentGroups) Then
           Call LogResults("CheckADSubscriptions()", "**** ERROR:  This machine has no group memberships. ****")
           for each Member in CurrentGroups
            Membername = Mid(Member,4,InStr(4,Member,",")-4)
            Call LogResults("CheckADSubscriptions()", "AD Group:  " & Membername)
            If Ucase(strADGroupName) = Ucase(Membername) Then
             Call LogResults("AD Group Membership has been confirmed", "****  AD Group:  " & Membername & "  ****")
             intReturnValue = 0
            End If
          End If

        If Err Then Call ErrorReport("CheckADSubscriptions")

        End Sub


        'Create the log file if it does not exist.
        Private Sub CreateLogFile


        On Error Resume Next


        Dim filesys, filetxt
        Set filesys = CreateObject("Scripting.FileSystemObject")

        If filesys.FileExists(strLogFile) Then

           Set filetxt = filesys.CreateTextFile(strLogFile, True) 

        End If

        End Sub


        'Write to the log.
        Private Sub LogResults(logTitle, logBody)


        On Error Resume Next

        Dim objTextStream
        set objTextStream=objfso.OpenTextFile(strLogFile, 8, true)

        objTextStream.WriteLine Now & "    " & logTitle & ":       " & logBody
        End Sub


        'Write any error information to the log
        Private Sub ErrorReport(strSub)


        On Error Resume Next

        Dim objTextStream01
        Dim TemFile01

        ErrorCount = ErrorCount + 1

        Set objTextStream01=objfso.OpenTextFile(strLogFile, 8, true)

        objTextStream01.WriteLine Now & "    " & ComputerName
        objTextStream01.WriteLine "   " & "Error Number:       " & Err.Number
        objTextStream01.WriteLine "   " & "Error Description:  " & Err.Description
        objTextStream01.WriteLine "   " & "Error Source:       " & Err.Source
        objTextStream01.WriteLine "   " & "From Sub:           " & strSub


        End Sub

        'Exit the script
        Private Sub EndScript()

        On Error Resume Next

        End Sub



        '======================Creates the log file if needed =====================================
        Call CreateLogFile()

        '======================Creates the log file if needed =====================================
        Call LogResults("/////////////////////////////// Starting AD Check ////////////////////////////////", "")

        '======================Gets the computer name =====================================
        Call LogResults("GetComputerName()", "Calling GetComputerName...")
        Call GetComputerName()

        '======================Gets the arguments passed thru by the BMC Channel =====================================
        Call LogResults("GetArguments()", "Calling GetArguments...")
        Call GetArguments()

        '======================Checkes AD Subscriptions for the Computer ===============================================
        Call LogResults("CheckADSubscriptions()", "Calling CheckADSubscriptions...")
        Call CheckADSubscriptions()

        '======================Return Value ===============================================
        Call LogResults("Return", "Returing the value:  " & intReturnValue)
        Call LogResults("====================== End AD Group Membership Check ===========================", "")

        return intReturnValue