Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hello,
I am stuck with a problem, Hope someone can help in sorting this.
We have a User directory connected to our QS environment and it has an attribute "Licensetype" in it. We also have a license rule set up to allocate the license. The rule is ((user.licensetype="Professional")) which automatically allocates the license.
The issue is when we remove the user from the user directory it reflects as an externally removed user in the Qlik user list but the license is still allocated to him and we have to manually deallocate the license.
Is there any way to automatically do this by amending the rules.?
My understanding is that the process flow is like User Directory -> Qlik User List ->professional access rules -> License allocated. Is there a frequency known on which the License rules are evaluated, like is it daily or depend on the user directory task.? I am thinking of amending the license rule to ((user.licensetype="Professional") and (user.removedExternally='True')) so that users which are removed are not allocated license on next evaluation. Anyone who has tried this approach?
Whoops, missed this. Here's an approach (it doesn't handle the token model but for you should be no issue):
#--------------------------------------------------------------------------------------------------------------------------------
#
# Script Name: qlik_sense_purge_removed_externally_users.ps1
# Description: Remove the assigned licenses of users who are marked as removed externally
# Dependency: Qlik-Cli (https://github.com/ahaydon/Qlik-Cli)
#
# Version Date Author Change Notes
# 0.1 2019-08-23 Levi Turner Initial version
#--------------------------------------------------------------------------------------------------------------------------------
# Helper function for recording timestamps in the logging
function Get-TimeStamp {
return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date)
}
# More verbose Get-QlikUser function
function Get-QlikUser {
[CmdletBinding()]
param (
[parameter(Position=0,ValueFromPipelinebyPropertyName=$true)]
[string]$id,
[string]$filter,
[switch]$full,
[switch]$raw
)
PROCESS {
$path = "/qrs/user"
If( $id ) { $path += "/$id" }
If( $full ) { $path += "/full" }
If( $raw ) { $rawOutput = $true }
$result = Invoke-QlikGet $path $filter
if( $raw -Or $full ) {
return $result
} else {
$properties = @('name','userDirectory','userId','id','removedExternally')
#if( $full ) { $properties += @('roles','inactive','blacklisted','removedExternally') }
return $result | Select-Object -Property $properties
}
}
}
# Helper function for removing Analyzer licenses; not found in Qlik-Cli when script was being built
function Remove-QlikAnalyzerAccessType {
[CmdletBinding()]
param (
[parameter(Position=0,ValueFromPipelinebyPropertyName=$true)]
[string]$id
)
PROCESS {
return Invoke-QlikDelete -path "/qrs/license/analyzeraccesstype/$id"
}
}
function Remove-QlikProfessionalAccessType {
[CmdletBinding()]
param (
[parameter(Position=0,ValueFromPipelinebyPropertyName=$true)]
[string]$id
)
PROCESS {
return Invoke-QlikDelete -path "/qrs/license/professionalaccesstype/$id"
}
}
# Logging
Set-Location $PSScriptRoot
$logdir = $PSScriptRoot + '\logs'
$logfile = $logdir + "\" + (Get-Date -Format yyyyMMdd) + ".log"
if (!(Test-Path $logdir)){
New-Item -path $logdir -type directory | Out-Null
}
# Connect to Qlik Sense
Connect-Qlik
# Clearing out Variables
$tokenusers = ''
# Get the version of QRS to figure out license model
$version = Invoke-QlikGet -path /qrs/about
Write-Output "$(Get-TimeStamp) : Build version: $($version.buildversion)" | Out-File -FilePath $logfile -Append
# If the version of QRS is less than April, tokens are being used, otherwise will need to check
if ($($version.buildVersion) -lt '20.4.2.0') {
Set-Variable -Name "licensemodel" -Value "token"
} else {
Set-Variable -Name "licensemodel" -Value "variable"
}
# Get list of users assigned named licenses
if ($($licensemodel) -eq 'variable') {
# if 2018-04 or higher then get the overview to later determine which license model is in effect
$LicenseOverview = Invoke-QlikGet -path /qrs/License/accesstypeoverview
Write-Output "$(Get-TimeStamp) : $($LicenseOverview)" | Out-File -FilePath $logfile -Append
if ($($LicenseOverview).totalTokens -eq '0') {
# If the totalTokens value in the LicenseOverview response zero, then get Professional User allocations
Set-Variable -Name "licensemodel" -Value "pa" -Force
$professionalusers = Invoke-QlikGet -path '/qrs/License/ProfessionalAccessType/full'
Write-Output "$(Get-TimeStamp) : $($professionalusers.count) professional licenses" | Out-File -FilePath $logfile -Append
$analyzerusers = Invoke-QlikGet -path '/qrs/License/AnalyzerAccessType/full'
Write-Output "$(Get-TimeStamp) : $($analyzerusers.count) analyzer licenses" | Out-File -FilePath $logfile -Append
} else {
# If the totalTokens value in the LicenseOverview response is non-zero then the token model is in use, get user access pass allocations
Set-Variable -Name "licensemodel" -Value "token" -Force
$tokenusers = Invoke-QlikGet -path '/qrs/License/UserAccessType/full'
Write-Output "$(Get-TimeStamp) : $($tokenusers.count) licenses" | Out-File -FilePath $logfile -Append
}
} else {
# if 2018-02 or earlier, then use token model and get user access pass allocations
Set-Variable -Name "licensemodel" -Value "token" -Force
$tokenusers = Invoke-QlikGet -path '/qrs/License/UserAccessType/full'
Write-Output "$(Get-TimeStamp) : $($tokenusers.count) licenses" | Out-File -FilePath $logfile -Append
}
# Remove-QlikProfessionalAccessType
# Remove-QlikUserAccessType
# Remove-QlikAnalyzerAccessType
# if/else for iterating over the users
# If the tokenusers variable is null iterate over the p/a users, else token users
if (!$tokenusers) {
# P/A Model
ForEach ($user in $professionalusers) {
$licenseusers = ''
$licenseusers = Get-QlikUser -id $user.user.id
if ($licenseusers.removedExternally -eq 'False') {
# Users are removedExternally = True
Write-Output "Removing Professional license for $($user.user.userDirectory)/$($user.user.userId) (User Name: $($user.user.name))" | Out-File -FilePath $logfile -Append
Remove-QlikProfessionalAccessType -id $user.id
} else {
# Users are removedExternally = False
}
}
ForEach ($analyzeruser in $analyzerusers) {
$analyzerlicenses = ''
$analyzerlicenses = Get-QlikUser -id $analyzeruser.user.id
if ($analyzerlicenses.removedExternally -eq 'False') {
# Users are removedExternally = True
Write-Output "Removing Analyzer license for $($analyzeruser.user.userDirectory)\$($analyzeruser.user.userId) (User Name: $($analyzeruser.user.name))" | Out-File -FilePath $logfile -Append
Remove-QlikAnalyzerAccessType -id $analyzeruser.id
} else {
# Users are removedExternally = False
}
}
} else {
Write-Host "Token model"
}
> If i delete a user from User directory and then from QMC will his license automatically gets deallocated.?
Yes (as well as assign ownership of any apps, sheets, etc to sa_repository).
just to clarify, you want a Security Rule that will deallocate license automatically? Security rules do not have that capability, and systematically there is nothing out of the box that could do that.
BR
Gio
License assignment is a 1 way process. So the work-flow is broadly like this:
So the user would be granted access based on (1).
So the options for license removal would be (a) manually de-allocate or (b) script a periodic de-allocation using the QRS API. For (b), I can come up with some demo code, but what license type are you using (i.e. tokens, professional / analyzer)?
Hi Gio,
I am looking for Professional access rule which might help in automatically deallocating the license.
Hi Levi,
Thanks for the insight, I thought that there would be a iteration where the license rule be evaluated and all the allocations are done. Considering that it works only one way i.e only allocation then changing the rule will not help.
Just like we have a checkbox to Allow Access in the Professional access rule section, Can we have a new rule like ((user.removedExternally='True')) and then untick the checkbox to not allow access. Can that work in de allocating license.?
I am using professional / analyzer license type, can you help with the QRS API code.? It looks the only way out.?
One more query, if you could help- If i delete a user from User directory and then from QMC will his license automatically gets deallocated.?
Whoops, missed this. Here's an approach (it doesn't handle the token model but for you should be no issue):
#--------------------------------------------------------------------------------------------------------------------------------
#
# Script Name: qlik_sense_purge_removed_externally_users.ps1
# Description: Remove the assigned licenses of users who are marked as removed externally
# Dependency: Qlik-Cli (https://github.com/ahaydon/Qlik-Cli)
#
# Version Date Author Change Notes
# 0.1 2019-08-23 Levi Turner Initial version
#--------------------------------------------------------------------------------------------------------------------------------
# Helper function for recording timestamps in the logging
function Get-TimeStamp {
return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date)
}
# More verbose Get-QlikUser function
function Get-QlikUser {
[CmdletBinding()]
param (
[parameter(Position=0,ValueFromPipelinebyPropertyName=$true)]
[string]$id,
[string]$filter,
[switch]$full,
[switch]$raw
)
PROCESS {
$path = "/qrs/user"
If( $id ) { $path += "/$id" }
If( $full ) { $path += "/full" }
If( $raw ) { $rawOutput = $true }
$result = Invoke-QlikGet $path $filter
if( $raw -Or $full ) {
return $result
} else {
$properties = @('name','userDirectory','userId','id','removedExternally')
#if( $full ) { $properties += @('roles','inactive','blacklisted','removedExternally') }
return $result | Select-Object -Property $properties
}
}
}
# Helper function for removing Analyzer licenses; not found in Qlik-Cli when script was being built
function Remove-QlikAnalyzerAccessType {
[CmdletBinding()]
param (
[parameter(Position=0,ValueFromPipelinebyPropertyName=$true)]
[string]$id
)
PROCESS {
return Invoke-QlikDelete -path "/qrs/license/analyzeraccesstype/$id"
}
}
function Remove-QlikProfessionalAccessType {
[CmdletBinding()]
param (
[parameter(Position=0,ValueFromPipelinebyPropertyName=$true)]
[string]$id
)
PROCESS {
return Invoke-QlikDelete -path "/qrs/license/professionalaccesstype/$id"
}
}
# Logging
Set-Location $PSScriptRoot
$logdir = $PSScriptRoot + '\logs'
$logfile = $logdir + "\" + (Get-Date -Format yyyyMMdd) + ".log"
if (!(Test-Path $logdir)){
New-Item -path $logdir -type directory | Out-Null
}
# Connect to Qlik Sense
Connect-Qlik
# Clearing out Variables
$tokenusers = ''
# Get the version of QRS to figure out license model
$version = Invoke-QlikGet -path /qrs/about
Write-Output "$(Get-TimeStamp) : Build version: $($version.buildversion)" | Out-File -FilePath $logfile -Append
# If the version of QRS is less than April, tokens are being used, otherwise will need to check
if ($($version.buildVersion) -lt '20.4.2.0') {
Set-Variable -Name "licensemodel" -Value "token"
} else {
Set-Variable -Name "licensemodel" -Value "variable"
}
# Get list of users assigned named licenses
if ($($licensemodel) -eq 'variable') {
# if 2018-04 or higher then get the overview to later determine which license model is in effect
$LicenseOverview = Invoke-QlikGet -path /qrs/License/accesstypeoverview
Write-Output "$(Get-TimeStamp) : $($LicenseOverview)" | Out-File -FilePath $logfile -Append
if ($($LicenseOverview).totalTokens -eq '0') {
# If the totalTokens value in the LicenseOverview response zero, then get Professional User allocations
Set-Variable -Name "licensemodel" -Value "pa" -Force
$professionalusers = Invoke-QlikGet -path '/qrs/License/ProfessionalAccessType/full'
Write-Output "$(Get-TimeStamp) : $($professionalusers.count) professional licenses" | Out-File -FilePath $logfile -Append
$analyzerusers = Invoke-QlikGet -path '/qrs/License/AnalyzerAccessType/full'
Write-Output "$(Get-TimeStamp) : $($analyzerusers.count) analyzer licenses" | Out-File -FilePath $logfile -Append
} else {
# If the totalTokens value in the LicenseOverview response is non-zero then the token model is in use, get user access pass allocations
Set-Variable -Name "licensemodel" -Value "token" -Force
$tokenusers = Invoke-QlikGet -path '/qrs/License/UserAccessType/full'
Write-Output "$(Get-TimeStamp) : $($tokenusers.count) licenses" | Out-File -FilePath $logfile -Append
}
} else {
# if 2018-02 or earlier, then use token model and get user access pass allocations
Set-Variable -Name "licensemodel" -Value "token" -Force
$tokenusers = Invoke-QlikGet -path '/qrs/License/UserAccessType/full'
Write-Output "$(Get-TimeStamp) : $($tokenusers.count) licenses" | Out-File -FilePath $logfile -Append
}
# Remove-QlikProfessionalAccessType
# Remove-QlikUserAccessType
# Remove-QlikAnalyzerAccessType
# if/else for iterating over the users
# If the tokenusers variable is null iterate over the p/a users, else token users
if (!$tokenusers) {
# P/A Model
ForEach ($user in $professionalusers) {
$licenseusers = ''
$licenseusers = Get-QlikUser -id $user.user.id
if ($licenseusers.removedExternally -eq 'False') {
# Users are removedExternally = True
Write-Output "Removing Professional license for $($user.user.userDirectory)/$($user.user.userId) (User Name: $($user.user.name))" | Out-File -FilePath $logfile -Append
Remove-QlikProfessionalAccessType -id $user.id
} else {
# Users are removedExternally = False
}
}
ForEach ($analyzeruser in $analyzerusers) {
$analyzerlicenses = ''
$analyzerlicenses = Get-QlikUser -id $analyzeruser.user.id
if ($analyzerlicenses.removedExternally -eq 'False') {
# Users are removedExternally = True
Write-Output "Removing Analyzer license for $($analyzeruser.user.userDirectory)\$($analyzeruser.user.userId) (User Name: $($analyzeruser.user.name))" | Out-File -FilePath $logfile -Append
Remove-QlikAnalyzerAccessType -id $analyzeruser.id
} else {
# Users are removedExternally = False
}
}
} else {
Write-Host "Token model"
}
> If i delete a user from User directory and then from QMC will his license automatically gets deallocated.?
Yes (as well as assign ownership of any apps, sheets, etc to sa_repository).
HOw to use this script:
Levi,
thanks for this snippet 🙂
From the point of view of licenses perspective:
Would this be a conceivable approach to (re)assign licenses to different users? Eg, day by day.
My customer is using the signed license key without Quarantine.
Thank you
\olli
anyone?
🙂
That approach would run afoul of the majority of contractual terms customers agree to. I'd suggest working with the account manager for your customer to clarify what the expected terms are.