cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

The Intelligent License Restriction has been introduced in FlexNet Manager and Flexera One ITAM in December 2022 (2022R2 version). The principle is super simple: Instead of restricting a license on an entity, you can restrict it on any "Device Group" or "User Group" depending on the device type.  These groups are defined with reports, that have to start from the "relevant object" (device or user).

The power of this restriction is that it defines a super flexible and dynamic target. For each reconciliation, the target list will be re-assessed and the License will try to "cover" the installations only for the "authorized scope".

When do you need the Intelligent Restriction? Very often actually. There are many cases when two licenses monitor the same applications in different metrics... for different populations of servers or  users. Here are some examples:

  • Prod / non Prod (IBM, Tibco)
  •  Server / Desktop (Java for contracts prior to January 2023)
  • High Density (Windows Server and Red Hat Data Center edition) / Low Density Clusters (Windows Server Standard or RHEL Server Node edition)
  • Non-Cloud Managed Services Providers (BYOL / PAYG): Can manage their license liability differently for VMs provided under contracts of services (Including Windows Server or SQL Server for instance) and others where this is not covered and customers are liable...

Non Prod License Restriction.png

Now you can restrict a license on any group, you can go one step further and use a license type I have personally found useless: the Microsoft User or Device CAL. This license type, provided you link the license to an application (any application) and that you set consumption based on access (and not CAL usage within a period) will show in the consumption ALL Users or ALL Devices. It may make sense for a Microsoft Core CAL but I have always tried to manage these licenses with a Named User with allocations, based on user entities or patterns in the account name ("Does not contain adm-" for instance).

If you combine the "brutal" Microsoft User or Device CAL license type with the subtle Intelligent restriction (a report with clever advanced filters), you can anticipate the "Intelligent Allocation" planned for later this year and have a license counting any Group of users (finally, a Core CAL license that counts well) or devices.

Let's move one step further and anticipate another planned enhancement in reporting: Showing the users to AD groups links in the report builder. Using the code below, and executing on the FNMSCompliance (sometimes named FNMP) database, you will create the "AD Group Object", that links to users and the user to AD Groups relationship. The quantity of records will need to be managed carefully with filters to avoid the 1 million record limit.

AD Groups Objects.png

You can now create a license that shows all users of one or multiple "Application Assignments" AD groups (Siebel Users, Acrobat users etc).

You can now create a license that counts and shows a group of users entitled for a license with no more need to allocate users or devices or look for installations. 

 

 

EXEC dbo.ComplianceTranslationPutByResourceStringCultureTypeResourceValue 'ComplianceSearchType.ActiveDirectoryGroup', N'en-US', 'AD Group'
EXEC dbo.ComplianceTranslationPutByResourceStringCultureTypeResourceValue 'ComplianceSearchTypeRelation.ADGroupToUsers', N'en-US',  'Users'
EXEC dbo.ComplianceTranslationPutByResourceStringCultureTypeResourceValue 'ComplianceSearchTypeRelation.UserToADGroups', N'en-US',  'AD Groups'

-- This script makes the following object types available for use in reports:
EXEC dbo.ComplianceTranslationPutByResourceStringCultureTypeResourceValue 'ComplianceSearchTypeColumn.ADGroupName', N'en-US', 'AD Group Name'
EXEC dbo.ComplianceTranslationPutByResourceStringCultureTypeResourceValue 'ComplianceSearchTypeColumn.ADGroupGUID', N'en-US', 'GUID'
EXEC dbo.ComplianceTranslationPutByResourceStringCultureTypeResourceValue 'ComplianceSearchTypeColumn.ActiveDirectoryGroupID', N'en-US', 'ActiveDirectoryGroupID'

GO

DECLARE @SearchName nvarchar(64), @tenant int
SET @SearchName = 'ADGroup' -- Name you want to display for object
SET @tenant = 1                     -- Tenant for which this view applies

EXEC ComplianceCustomViewTypeRegister
        @TenantID = @tenant,              -- REQUIRED
      @TypeName = @SearchName,            -- Name displayed in GUI for Object
	  @TypeNameResourceName = 'ComplianceSearchType.ActiveDirectoryGroup',
      @QuerySetup =
'-- Pre-calculate computers that user is allowed access
	CREATE TABLE #ADGroupsAllowed (ActiveDirectoryGroupID int PRIMARY KEY (ActiveDirectoryGroupID))
	INSERT  #ADGroupsAllowed SELECT DISTINCT adg.ActiveDirectoryGroupID FROM dbo.ActiveDirectoryGroup adg-- there is no restriction on AD groups but through authorized users 
																	  JOIN ActiveDirectoryMember gu on gu.ParentGroupGUID = adg.GUID
																	  JOIN ActiveDirectoryUser adu on adu.GUID = gu.GUID
																	  JOIN ActiveDirectoryDomain ad on ad.ActiveDirectoryDomainID = adu.ActiveDirectoryDomainID
																	  JOIN ComplianceDomain cd on cd.FlatName = ad.FlatName AND ad.QualifiedName = cd.QualifiedName
																	  JOIN ComplianceUserCurrentUserScoped cu on adu.SAMAccountName = cu.SAMAccountName
																	  AND cu.ComplianceDomainID = cd.ComplianceDomainID	',
      @QueryFilter = 
'
-- Pre-calculate AD Groups match filter
	CREATE TABLE #{NAMESPACE}ADGroupFilter (ActiveDirectoryGroupID int PRIMARY KEY)
	INSERT  #{NAMESPACE}ADGroupFilter
	SELECT  DISTINCT ActiveDirectoryGroup.ActiveDirectoryGroupID 
	FROM     dbo.ActiveDirectoryGroup AS ActiveDirectoryGroup
			INNER JOIN #ADGroupsAllowed AS ad_allowed ON ad_allowed.ActiveDirectoryGroupID = ActiveDirectoryGroup.ActiveDirectoryGroupID
			{QUERYFROM}
	WHERE   {QUERYWHERE}

',
      @IsCustom = 1,
      @QueryTemplate =
'

-- Custom view query for ADGroup
	SELECT  {QUERYSELECT}
	FROM    dbo.ActiveDirectoryGroup AS ActiveDirectoryGroup
			-- Filter
			INNER JOIN {FILTER|#{NAMESPACE}ADGroupFilter|#ADGroupsAllowed} AS filter ON filter.ActiveDirectoryGroupID = ActiveDirectoryGroup.ActiveDirectoryGroupID
			-- Additional joins
			{QUERYFROM}
	WHERE   {QUERYWHERE}

	'

-- Link to users
exec dbo.ComplianceCustomViewRelationRegister
@TenantID = @tenant,
@RelationName = 'ADGroupToUsers',
@DescriptionResourceName = 'ComplianceSearchTypeRelation.ADGroupToUsers',
@DescriptionDefault = 'Users',
@FromSearchType = 'ADGroup',
@ToSearchType = 'User',
@ToMany = 1,
@JoinClause = '
-- Link from AD Group to Compliance User
	LEFT OUTER JOIN
	(SELECT adg.ActiveDirectoryGroupID, Users.*
FROM ActiveDirectoryGroup adg
	JOIN ActiveDirectoryMember gu on gu.ParentGroupGUID = adg.GUID
	JOIN ActiveDirectoryUser adu on adu.GUID = gu.GUID
	JOIN ActiveDirectoryDomain ad on ad.ActiveDirectoryDomainID = adu.ActiveDirectoryDomainID
	JOIN ComplianceDomain cd on cd.FlatName = ad.FlatName AND ad.QualifiedName = cd.QualifiedName
	JOIN ComplianceUserCurrentUserScoped cu on adu.SAMAccountName = cu.SAMAccountName
					AND cu.ComplianceDomainID = cd.ComplianceDomainID
	INNER JOIN (
			{SUBQUERY}
	) AS Users  ON Users.{NAMESPACE}UserID = cu.ComplianceUserID
) as ADGroupToUsers on ADGroupToUsers.ActiveDirectoryGroupID = ActiveDirectoryGroup.ActiveDirectoryGroupID
	'
	,
@FilterClause = '

	LEFT OUTER JOIN ActiveDirectoryGroup AS {NAMESPACE}ActiveDirectoryGroup
				JOIN ActiveDirectoryMember gu on gu.ParentGroupGUID = {NAMESPACE}ActiveDirectoryGroup.GUID
				JOIN ActiveDirectoryUser adu on adu.GUID = gu.GUID
				JOIN ActiveDirectoryDomain ad on ad.ActiveDirectoryDomainID = adu.ActiveDirectoryDomainID
				JOIN ComplianceDomain cd on cd.FlatName = ad.FlatName AND ad.QualifiedName = cd.QualifiedName
				JOIN ComplianceUserCurrentUserScoped cu on adu.SAMAccountName = cu.SAMAccountName
					AND cu.ComplianceDomainID = cd.ComplianceDomainID
			ON {NAMESPACE}ActiveDirectoryGroup.ActiveDirectoryGroupID = {PARENTNAMESPACE}ActiveDirectoryGroup.ActiveDirectoryGroupID
	LEFT OUTER JOIN #ComplianceUserAllowed AS {NAMESPACE}allowed ON {NAMESPACE}allowed.ComplianceUserID = cu.ComplianceUserID -- should maybe be: {NAMESPACE}ActiveDirectoryGroup
	LEFT OUTER JOIN ComplianceUser AS {NAMESPACE}ComplianceUser ON {NAMESPACE}ComplianceUser.ComplianceUserID = {NAMESPACE}allowed.ComplianceUserID
'
,
@IsCustom = 1

-- -- Link from user to AD groups

exec dbo.ComplianceCustomViewRelationRegister
@TenantID = @tenant,
@RelationName = 'UserToADGroups',
@DescriptionResourceName = 'ComplianceSearchTypeRelation.UserToADGroups',
@DescriptionDefault = 'ADGroups',
@FromSearchType = 'User',
@ToSearchType = 'ADGroup',
@ToMany = 1,
@JoinClause = 
'
-- Link from User to AD Groups
	LEFT OUTER JOIN
	(SELECT cu.ComplianceUserID, ADGroups.*
FROM ActiveDirectoryGroup adg
	JOIN ActiveDirectoryMember gu on gu.ParentGroupGUID = adg.GUID
	JOIN ActiveDirectoryUser adu on adu.GUID = gu.GUID
	JOIN ActiveDirectoryDomain ad on ad.ActiveDirectoryDomainID = adu.ActiveDirectoryDomainID
	JOIN ComplianceDomain cd on cd.FlatName = ad.FlatName AND ad.QualifiedName = cd.QualifiedName
	JOIN ComplianceUserCurrentUserScoped cu on adu.SAMAccountName = cu.SAMAccountName
					AND cu.ComplianceDomainID = cd.ComplianceDomainID
	INNER JOIN (
			{SUBQUERY}
	) AS ADGroups  ON ADGroups.{NAMESPACE}ActiveDirectoryGroupID = adg.ActiveDirectoryGroupID
) as UserToADGroups on UserToADGroups.ComplianceUserID = ComplianceUser.ComplianceUserID
'
	,
@FilterClause = '

	LEFT OUTER JOIN ComplianceUser AS {NAMESPACE}ComplianceUser
				JOIN ComplianceDomain cd on cd.ComplianceDomainID = {NAMESPACE}ComplianceUser.ComplianceDomainID
				JOIN ActiveDirectoryDomain ad on cd.FlatName = ad.FlatName AND ad.QualifiedName = cd.QualifiedName
				JOIN ActiveDirectoryUser adu on adu.SAMAccountName = {NAMESPACE}ComplianceUser.SAMAccountName
									AND adu.ActiveDirectoryDomainID = ad.ActiveDirectoryDomainID
				JOIN ActiveDirectoryMember gu on gu.GUID = adu.GUID
				JOIN ActiveDirectoryGroup adg on adg.GUID = gu.ParentGroupGUID		
			ON {NAMESPACE}ComplianceUser.ComplianceUserID = ComplianceUser.ComplianceUserID
	LEFT OUTER JOIN #ADGroupsAllowed AS {NAMESPACE}allowed ON {NAMESPACE}allowed.ActiveDirectoryGroupID = adg.ActiveDirectoryGroupID -- should maybe be: {NAMESPACE}ActiveDirectoryGroup
	LEFT OUTER JOIN ActiveDirectoryGroup AS {NAMESPACE}ActiveDirectoryGroup ON {NAMESPACE}ActiveDirectoryGroup.ActiveDirectoryGroupID = {NAMESPACE}allowed.ActiveDirectoryGroupID
'
,
@IsCustom = 1

EXEC ComplianceCustomViewColumnRegister
        @TenantID = @tenant,              -- REQUIRED - set Tenant
        @ComplianceSearchType = @SearchName, --REQUIRED - links to object
      @ColumnName = 'ADGroup.ActiveDirectoryGroupID', -- column name displayed in GUI
      @ColumnNameResourceName = 'ComplianceSearchTypeColumn.ActiveDirectoryGroupID',
      @SelectName = 'ActiveDirectoryGroup.ActiveDirectoryGroupID',  -- view\column from query
      @WhereClause = 'ActiveDirectoryGroup.ActiveDirectoryGroupID', -- view\column from query
      @FilterGroupType = 2, -- do not change
      @DefaultFilterType = 1, -- do not change
      @SelectByDefault = 0, -- 1 = box is checked for view; 0 = box is not checked for view
	  @Mandatory = 1,
	  @PrimaryKey = 1



EXEC ComplianceCustomViewColumnRegister
        @TenantID = @tenant,              -- REQUIRED - set Tenant
        @ComplianceSearchType = @SearchName, --REQUIRED - links to object
      @ColumnName = 'ADGroup.ADGroupName', -- column name displayed in GUI
      @ColumnNameResourceName = 'ComplianceSearchTypeColumn.ADGroupName',
      @SelectName = 'ActiveDirectoryGroup.Name',  -- view\column from query
      @WhereClause = 'ActiveDirectoryGroup.Name', -- view\column from query
      @FilterGroupType = 1, -- do not change
      @DefaultFilterType = 1, -- do not change
      @SelectByDefault = 1 -- 1 = box is checked for view; 0 = box is not checked for view

EXEC ComplianceCustomViewColumnRegister
        @TenantID = @tenant,              -- REQUIRED - set Tenant
        @ComplianceSearchType = @SearchName, --REQUIRED - links to object
      @ColumnName = 'ADGroup.GUID', -- column name displayed in GUI
      @ColumnNameResourceName = 'ComplianceSearchTypeColumn.ADGroupGUID',
      @SelectName = 'ActiveDirectoryGroup.GUID',  -- view\column from query
      @WhereClause = 'ActiveDirectoryGroup.GUID', -- view\column from query
      @FilterGroupType = 1, -- do not change
      @DefaultFilterType = 1, -- do not change
      @SelectByDefault = 0 -- 1 = box is checked for view; 0 = box is not checked for view




 




Learn more: If applicable, you can include links to related knowledge base articles or how-tos.

Was this article helpful? Yes No
100% helpful (1/1)
Version history
Last update:
‎Jun 21, 2023 07:58 PM
Updated by: