Qlik-Cli.psm1
$script:guid = "^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$" $script:isDate = "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$" if( $qlik_output_raw ) { $rawOutput = $true } ################################################################################################### # Internal helper functions ################################################################################################### function GetXrfKey() { $alphabet = $Null; For ($a=97;$a -le 122;$a++) { $alphabet += ,[char][byte]$a } For ($loop=1; $loop -le 16; $loop++) { $key += ($alphabet | Get-Random) } return $key } function DeepCopy($data) { $ms = New-Object System.IO.MemoryStream $bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $bf.Serialize($ms, $data) $ms.Position = 0 $dataDeep = $bf.Deserialize($ms) $ms.Close() return $dataDeep } function GetCustomProperties($customProperties) { $prop = @( $customProperties | foreach { $val = $_ -Split "=" $p = Get-QlikCustomProperty -filter "name eq '$($val[0])'" @{ value = ($p.choiceValues -eq $val[1])[0] definition = $p } } ) return $prop } function GetTags($tags) { $prop = @( $tags | foreach { $p = Get-QlikTag -filter "name eq '$_'" @{ id = $p.id } } ) return $prop } function CallRestUri($method, $path, $extraParams) { Write-Verbose "Raw output: $rawOutput" If( $Script:prefix -eq $null ) { Connect-Qlik > $null } If( ! $path.StartsWith( "http" ) ) { $path = $Script:prefix + $path } $xrfKey = GetXrfKey If( $path.contains("?") ) { $path += "&xrfkey=$xrfKey" } else { $path += "?xrfkey=$xrfKey" } $params = DeepCopy $api_params If( $extraParams ) { $params += $extraParams } If( !$params.Header ) { $params.Header = @{} } If( !$params.Header.ContainsKey("x-Qlik-Xrfkey") ) { Write-Verbose "Adding header x-Qlik-Xrfkey: $xrfKey" $params.Header.Add("x-Qlik-Xrfkey", $xrfKey) } If( $params.Body ) { Write-Verbose $params.Body } Write-Verbose "Calling $method for $path" If( $script:webSession -eq $null ) { $result = Invoke-RestMethod -Method $method -Uri $path @params -SessionVariable webSession $script:webSession = $webSession } else { $result = Invoke-RestMethod -Method $method -Uri $path @params -WebSession $script:webSession } if( !$rawOutput ) { Write-Verbose "Formatting response" $result = FormatOutput($result) } return $result } function FetchCertificate($storeName, $storeLocation) { $certFindValue = "CN=QlikClient" $store = New-Object System.Security.Cryptography.X509Certificates.X509Store $storeName, $storeLocation $certs = @() try { $store.Open("ReadOnly") $certs = $store.Certificates.Find("FindBySubjectDistinguishedName", $certFindValue, $false) } catch { Write-Host "Caught an exception:" -ForegroundColor Red Write-Host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red Write-Host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red } finally{ $store.Close() } return $certs } function FormatOutput($objects, $schemaPath) { Write-Debug "Resolving enums" If( !$Script:enums ) { $rawOutput = $true # If enums haven't been read get them and save them for later use $enums = Invoke-QlikGet "/qrs/about/api/enums" $Script:enums = $enums | Get-Member -MemberType NoteProperty | foreach { $enums.$($_.Name) } } If( !$Script:relations ) { # If relations haven't been read get them and save them for later use $Script:relations = Get-QlikRelations } foreach( $object in $objects ) { # Determine the object type being formatted If( !$schemaPath ) { $schemaPath = $object.schemaPath } Write-Debug "Schema path: $schemaPath" foreach( $prop in ( $object | Get-Member -MemberType NoteProperty ) ) { If( $object.$($prop.Name) -is [string] -And $object.$($prop.Name) -match $isDate ) { # Update any value that looks like a date to a more human readable format $object.$($prop.Name) = Get-Date -Format "yyyy/MM/dd HH:mm" $object.$($prop.Name) } Write-Debug "Property: $schemaPath.$($prop.Name)" # Find enums related to the current object property $enumsRelated = $Script:enums | where-object { $_.Usages -contains "$schemaPath.$($prop.Name)" } If( $enumsRelated ) { # If there is an enum for the property then resolve it $value = ((($enumsRelated | select -expandproperty values | where {$_ -like "$($object.$($prop.Name)):*" }) -split ":")[1]).TrimStart() Write-Debug "Resolving $($prop.Name) from $($object.$($prop.Name)) to $value" $object.$($prop.Name) = $value } # Check for relations referenced by the property $relatedRelations = $Script:relations -like "$schemaPath.$($prop.Name) > *" If( $relatedRelations ) { # If there are relations for the property then call self for the object Write-Debug "Traversing $($prop.Name)" $object.$($prop.Name) = FormatOutput $object.$($prop.Name) $(($relatedRelations -Split ">")[1].TrimStart()) } } } return $objects } ################################################################################################### # Cmdlets functions ################################################################################################### function Add-QlikProxy { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$ProxyId, [parameter(Mandatory=$true,Position=1)] [string]$VirtualProxyId ) PROCESS { $proxy = Get-QlikProxy -raw $ProxyId $vp = Get-QlikVirtualProxy -raw $VirtualProxyId $proxy.settings.virtualProxies += $vp $json = $proxy | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/proxyservice/$ProxyId" $json } } function Add-QlikTrigger { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [alias("id")] [string]$taskId, [string[]]$OnSuccess, [string]$date ) PROCESS { If( $tags ) { $tagArray = @( $tags | foreach { $p = Get-QlikTag -filter "name eq '$_'" @{ id = $p.id } } ) } else { $tagArray = @(); } $task = Get-QlikReloadTask -id $taskId -raw If($date) { $date = Get-Date -Format yyyy-MM-ddTHH:mm:ss.000Z $date $update = @{ schemaEvents = @(@{ name = "Daily"; enabled = $true; eventType = 0; startDate = "$date"; expirationDate = "9999-12-30T23:59:59.999Z"; schemaFilterDescription = @("* * - * * * * *"); incrementDescription = "0 0 1 0"; incrementOption = "2"; reloadTask = @{ id = $task.id } }) } } else { $update = @{ compositeEvents = @( @{ name="TRANSFORM OnSuccess"; enabled=$true; eventType=1; reloadTask = @{ id = $task.id } timeConstraint=@{ seconds = 0; minutes = 360; hours = 0; days = 0; }; compositeRules=@($OnSuccess | foreach { @{ ruleState=1; reloadTask=@{ id=$_ } } }); privileges=@("read","update","create","delete") } ) } } $json = $update | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost "/qrs/reloadtask/update" $json } } function Add-QlikVirtualProxy { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [alias("engine")] [string[]]$loadBalancingServerNodes, [alias("wsorigin")] [string[]]$websocketCrossOriginWhiteList ) PROCESS { $proxy = Get-QlikVirtualProxy -raw $id $params = $psBoundParameters If( $params.ContainsKey("loadBalancingServerNodes") ) { $params["loadBalancingServerNodes"] = @( $proxy.loadBalancingServerNodes | foreach { $_.id } ) + $loadBalancingServerNodes } If( $params.ContainsKey("websocketCrossOriginWhiteList") ) { $params["websocketCrossOriginWhiteList"] = $proxy.websocketCrossOriginWhiteList + $websocketCrossOriginWhiteList } return Update-QlikVirtualProxy @params } } function Connect-Qlik { <# .SYNOPSIS Establishes a session with a Qlik Sense server, other Qlik cmdlets will use this session to invoke commands. .DESCRIPTION Uses the parameter values to establish a new session with a Sense server, if a valid certificate can be found in the Windows certificate store it will be used unless this is overridden by the certificate parameter. If a valid certificate cannot be found Windows authentication will be attempted using the credentials of the user that is running the PowerShell console. .EXAMPLE Connect-Qlik -computername CentralNodeName -username domain\username .LINK https://github.com/ahaydon/Qlik-Cli #> [CmdletBinding(DefaultParameterSetName="Certificate")] param ( # Name of the Sense server to connect to [parameter(Position=0)] [string]$Computername, # Disable checking of certificate trust [switch]$TrustAllCerts, # UserId to use with certificate authentication in the format domain\username [Parameter(ParameterSetName = "Certificate")] [string]$Username = "$($env:userdomain)\$($env:username)", # Client certificate to use for authentication [parameter(ParameterSetName = "Certificate", ValueFromPipeline=$true)] [System.Security.Cryptography.X509Certificates.X509Certificate]$Certificate, # Credentials to use when connecting via proxy [parameter(ParameterSetName = "Credential")] [PSCredential]$Credential, # Use credentials of logged on user for authentication, prevents automatically locating a certificate [parameter(ParameterSetName = "Default")] [switch]$UseDefaultCredentials ) PROCESS { # Since we are connecting we need to clear any variables relating to previous connections $script:api_params = $null $script:prefix = $null $script:webSession = $null If( $TrustAllCerts ) { add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy } If( !$Certificate -And !$Credential -And !$UseDefaultCredentials ) { $certs = @(FetchCertificate "My" "CurrentUser") Write-Verbose "Found $($certs.Count) certificates in CurrentUser store" If( $certs.Count -eq 0 ) { $certs = @(FetchCertificate "My" "LocalMachine") Write-Verbose "Found $($certs.Count) certificates in LocalMachine store" } If( $certs.Count -gt 0 ) { $Certificate = $certs[0] } } If( $Certificate ) { Write-Verbose "Using certificate $($Certificate.FriendlyName)" $Script:api_params = @{ Certificate=$Certificate Header=@{"X-Qlik-User" = $("UserDirectory={0};UserId={1}" -f $($username -split "\\"))} } $port = ":4242" } ElseIf( $Credential ) { Write-Verbose $("Using credentials for {0}" -f $Credential.Username) $Script:api_params = @{ Credential=$Credential } } Else { Write-Verbose "No valid certificate found, using Windows credentials" $Script:api_params = @{ UseDefaultCredentials=$true } } If ( $Computername ) { If( $Computername.ToLower().StartsWith( "http" ) ) { $Script:prefix = $Computername } else { $Script:prefix = "https://" + $Computername + $port } } else { $Script:prefix = "https://" + $env:computername + $port } $result = Get-QlikAbout return $result } } Set-Alias -Name Qonnect -Value Connect-Qlik function Copy-QlikApp { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [parameter(ValueFromPipelinebyPropertyName=$True,Position=1)] [string]$name ) PROCESS { $path = "/qrs/app/$id/copy" If( $name ) { $path += "?name=$name" } return Invoke-QlikPost $path } } function Export-QlikApp { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [parameter(ValueFromPipelinebyPropertyName=$True,Position=1)] [string]$filename ) PROCESS { Write-Verbose filename=$filename If( [string]::IsNullOrEmpty($filename) ) { $file = "$id.qvf" } else { $file = $filename } Write-Verbose file=$file $app = (Invoke-QlikGet /qrs/app/$id/export).value Invoke-QlikDownload "/qrs/download/app/$id/$app/temp.qvf" $file Write-Verbose "Downloaded $id to $file" } } function Export-QlikCertificates { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string[]]$machineNames, [SecureString]$certificatePassword, [switch]$includeSecretsKey, [ValidateSet("Windows", "Pem")] [String]$exportFormat="Windows" ) PROCESS { Write-Verbose "Export path: $(Get-QlikCertificateDistributionPath)" $body = @{ machineNames = @( $machineNames ); } If( $certificatePassword ) { $body.certificatePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($CertificatePassword)) } If( $includeSecretsKey ) { $body.includeSecretsKey = $true } If( $exportFormat ) { $body.exportFormat = $exportFormat } $json = $body | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost "/qrs/certificatedistribution/exportcertificates" $json } } function Get-QlikAbout { PROCESS { return Invoke-QlikGet "/qrs/about" } } function Get-QlikApp { [CmdletBinding(DefaultParameterSetName="Multi")] param ( [parameter(ParameterSetName="Single",Mandatory=$false,Position=0)] [string]$id, [parameter(ParameterSetName="Multi",Mandatory=$false)] [string]$filter, [parameter(ParameterSetName="Multi",Mandatory=$false)] [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/app" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikAccessTypeInfo { PROCESS { return Invoke-QlikGet "/qrs/license/accesstypeinfo" } } function Get-QlikCertificateDistributionPath { [CmdletBinding()] param ( ) PROCESS { $path = "/qrs/certificatedistribution/exportcertificatespath" return Invoke-QlikGet -Path $path } } function Get-QlikContentLibrary { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/contentlibrary" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikCustomProperty { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/custompropertydefinition" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikDataConnection { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/dataconnection" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikEngine { [CmdletBinding()] param ( [parameter(Position=0, ValueFromPipelinebyPropertyName=$true)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/engineservice" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikExtension { [CmdletBinding()] param ( [parameter(Position=0)] [string]$Id, [string]$Filter, [switch]$Full, [switch]$raw ) PROCESS { $Path = "/qrs/extension" If( $Id ) { $Path += "/$Id" } If( $Full ) { $Path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet -Path $Path -Filter $Filter } } function Get-QlikLicense { PROCESS { return Invoke-QlikGet "/qrs/license" } } function Get-QlikLicenseAudit { [CmdletBinding()] param ( [string]$resourceType, [string]$resourceFilter, [string]$userFilter, [string]$environmentAttributes, [int]$userSkip, [int]$userTake, [int]$resourceSkip, [int]$resourceTake, [switch]$includeNonGrantingRules, [parameter(ValueFromPipelinebyPropertyName=$true)] [alias("id")] [string]$resourceId, [switch]$raw ) PROCESS { $params = @{ resourceType = $resourceType; resourceFilter = $resourceFilter; userFilter = $userFilter; environmentAttributes = $environmentAttributes; userSkip = $userSkip; userTake = $userTake; resourceSkip = $resourceSkip; resourceTake = $resourceTake; } If( $includeNonGrantingRules ) { $params.includeNonGrantingRules = $true } If( $resourceId ) { $params.resourceFilter = "id eq $resourceId" } $json = $params | ConvertTo-Json -Compress -Depth 10 If( $raw ) { $rawOutput = $true } return Invoke-QlikPost "/qrs/systemrule/license/audit" $json } } function Get-QlikLoginAccess { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/license/loginAccessType" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikNode { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$count, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/servernodeconfiguration" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $count -And (-not ($id -And $full)) ) { $path += "/count" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikObject { [CmdletBinding(DefaultParameterSetName="Multi")] param ( [parameter(ParameterSetName="Single",Mandatory=$false,Position=0)] [string]$id, [parameter(ParameterSetName="Multi",Mandatory=$false)] [string]$filter, [parameter(ParameterSetName="Multi",Mandatory=$false)] [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/app/object" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikProxy { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/proxyservice" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikRelations { PROCESS { return Invoke-QlikGet "/qrs/about/api/relations" } } function Get-QlikRule { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/systemrule" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikReloadTask { [CmdletBinding()] param ( [parameter(Position=0)] [string]$Id, [string]$Filter, [switch]$Full, [switch]$raw ) PROCESS { $path = "/qrs/reloadtask" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet -Path $path -Filter $filter } } function Get-QlikScheduler { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$count, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/schedulerservice" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $count -And (-not ($id -And $full)) ) { $path += "/count" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikServiceCluster { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$count, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/ServiceCluster" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $count -And (-not ($id -And $full)) ) { $path += "/count" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikSession { [CmdletBinding(DefaultParameterSetName="User")] param ( [parameter(ParameterSetName="Id",Mandatory=$true,Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id, [parameter(ParameterSetName="User",Mandatory=$true,Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$userDirectory, [parameter(ParameterSetName="User",Mandatory=$true,Position=1,ValueFromPipelinebyPropertyName=$true)] [string]$userId, [alias("vp")] [string]$virtualProxyPrefix, [switch]$raw ) PROCESS { $proxy = Get-QlikProxy local $prefix = "https://$($proxy.serverNodeConfiguration.hostName):$($proxy.settings.restListenPort)/qps" if ($virtualProxyPrefix) { $prefix += "/$virtualProxyPrefix" } if ($id) { $path = "$prefix/session/$id" } else { $path = "$prefix/user/$userDirectory/$userId" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path } } function Get-QlikStream { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/stream" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikTag { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/tag" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikTask { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/task" If( !$raw ) { If( $id ) { $path += "/$id" } $path += "/full" $result = Invoke-QlikGet $path $filter If( !$full ) { $result = $result | foreach { $props = @{ name = $_.name status = $_ | select -ExpandProperty operational | select -ExpandProperty lastExecutionResult | select -ExpandProperty status lastExecution = $_ | select -ExpandProperty operational | select -ExpandProperty lastExecutionResult | select -ExpandProperty startTime nextExecution = $_ | select -ExpandProperty operational | select -ExpandProperty nextExecution } New-Object -TypeName PSObject -Prop $props } } return $result } else { If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } } 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') #if( $full ) { $properties += @('roles','inactive','blacklisted','removedExternally') } return $result | select -Property $properties } } } function Get-QlikUserAccessType { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/license/useraccesstype" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikUserDirectory { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/userdirectory" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Get-QlikValidEngines { [CmdletBinding()] param ( [parameter(Position=0)] [string]$proxyId, [parameter(Position=1)] [string]$proxyPrefix, [parameter(Position=2)] [string]$appId, [parameter(Position=3)] [ValidateSet("Production","Development","Any")] [string]$loadBalancingPurpose, [switch]$raw ) PROCESS { $json = (@{ proxyId = $proxyId; proxyPrefix = $proxyPrefix; appId = $appId; loadBalancingPurpose = $loadBalancingPurpose } | ConvertTo-Json -Compress -Depth 10) If( $raw ) { $rawOutput = $true } Invoke-QlikPost "/qrs/loadbalancing/validengines" $json } } function Get-QlikVirtualProxy { [CmdletBinding()] param ( [parameter(Position=0)] [string]$id, [string]$filter, [switch]$full, [switch]$raw ) PROCESS { $path = "/qrs/virtualproxyconfig" If( $id ) { $path += "/$id" } If( $full ) { $path += "/full" } If( $raw ) { $rawOutput = $true } return Invoke-QlikGet $path $filter } } function Import-QlikApp { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$file, [parameter(Position=1)] [string]$name, [string]$replace, [switch]$upload ) PROCESS { If( $name ) { $appName = $name } Else { $appName = $(gci $file).BaseName } $path = "/qrs/app/{0}?name=$appName" If( $replace ) { $path += "&replace=$replace" } If( $upload ) { $path = $path -f 'upload' return Invoke-QlikUpload $path $file } else { $path = $path -f 'import' return Invoke-QlikPost $path $file } } } function Import-QlikExtension { [CmdletBinding()] param ( [String]$ExtensionPath, [String]$Password ) PROCESS { $Path = "/qrs/extension/upload" if($Password) { $Path += "?password=$Password" } return Invoke-QlikUpload $Path $ExtensionPath } } function Import-QlikObject { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)] [PSObject[]]$object ) PROCESS { $object | foreach { $path = "/qrs/{0}" -F $_.schemaPath $json = $_ | ConvertTo-Json -Compress -Depth 10 Invoke-QlikPost $path $json } } } function Invoke-QlikDelete { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$path ) PROCESS { return CallRestUri Delete $path } } function Invoke-QlikGet { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$path, [parameter(Position=1)] [string]$filter ) PROCESS { If( $filter ) { If( $path.contains("?") ) { $path += "&filter=$filter" } else { $path += "?filter=$filter" } } return CallRestUri Get $path } } function Invoke-QlikPost { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$path, [parameter(Position=1,ValueFromPipeline=$true)] [string]$body, [string]$contentType = "application/json" ) PROCESS { $params = @{ ContentType = $contentType Body = $body } return CallRestUri Post $path $params } } function Invoke-QlikPut { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$path, [parameter(Position=1)] [string]$body ) PROCESS { $params = @{ ContentType = "application/json" Body = $body } return CallRestUri Put $path $params } } function Invoke-QlikDownload { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$path, [parameter(Mandatory=$true,Position=1)] [string]$filename ) PROCESS { $params = @{ OutFile = $filename } return CallRestUri Get $path $params } } function Invoke-QlikUpload { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$path, [parameter(Mandatory=$true,Position=1)] [string]$filename ) PROCESS { $params = @{ InFile = $filename ContentType = "application/vnd.qlik.sense.app" } return CallRestUri Post $path $params } } function New-QlikCustomProperty { [CmdletBinding()] param ( [string]$name, [string]$valueType = "Text", [string[]]$choiceValues, [ValidateSet("App","ContentLibrary","DataConnection","EngineService","Extension","ProxyService","ReloadTask","RepositoryService","SchedulerService","ServerNodeConfiguration","Stream","User","UserSyncTask","VirtualProxyConfig", IgnoreCase=$false)] [string[]]$objectTypes ) PROCESS { $json = @{ name = $name; valueType = $valueType; objectTypes = $objectTypes } if($ChoiceValues) { $json.Add("ChoiceValues", $ChoiceValues) } $json = $json | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost "/qrs/custompropertydefinition" $json } } function New-QlikDataConnection { [CmdletBinding()] param ( [parameter(Position=0)] [string]$name, [parameter(Position=1)] [string]$connectionstring, [parameter(Position=2)] [string]$type, [string[]]$customProperties, [string[]]$tags, [string]$username, [string]$password ) PROCESS { $json = @{ customProperties=@(); engineObjectId=[Guid]::NewGuid(); username=$username; password=$password; name=$name; connectionstring=$connectionstring; type=$type } If( $customProperties ) { $prop = @( $customProperties | foreach { $val = $_ -Split "=" $p = Get-QlikCustomProperty -filter "name eq '$($val[0])'" @{ value = ($p.choiceValues -eq $val[1])[0] definition = $p } } ) $json.customProperties = $prop } If( $tags ) { $prop = @( $tags | foreach { $p = Get-QlikTag -filter "name eq '$_'" @{ id = $p.id } } ) $json.tags = $prop } $json = $json | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost "/qrs/dataconnection" $json } } function New-QlikNode { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$hostname, [string]$name = $hostname, [string]$nodePurpose, [string[]]$customProperties, [string[]]$tags, [alias("engine")] [switch]$engineEnabled, [alias("proxy")] [switch]$proxyEnabled, [alias("scheduler")] [switch]$schedulerEnabled, [alias("printing")] [switch]$printingEnabled, [alias("failover")] [switch]$failoverCandidate ) PROCESS { $json = (@{ configuration=@{ name=$name; hostName=$hostname; engineEnabled=$engineEnabled.IsPresent; proxyEnabled=$proxyEnabled.IsPresent; schedulerEnabled=$schedulerEnabled.IsPresent; printingEnabled=$printingEnabled.IsPresent; failoverCandidate=$failoverCandidate.IsPresent; } } | ConvertTo-Json -Compress -Depth 10) $container = Invoke-QlikPost "/qrs/servernodeconfiguration/container" $json #Write-Host "http://localhost:4570/certificateSetup" return Invoke-QlikGet "/qrs/servernoderegistration/start/$($container.configuration.id)" } } function New-QlikRule { [CmdletBinding()] param ( [parameter(ValueFromPipeline=$true)] [PSObject]$object, [string]$name, [ValidateSet("License","Security","Sync")] [string]$category, [string]$rule, [alias("filter")] [string]$resourceFilter, [ValidateSet("hub","qmc","both")] [alias("context")] [string]$rulecontext = "both", [int]$actions, [string]$comment, [switch]$disabled ) PROCESS { If( $object ) { $json = $object | ConvertTo-Json -Compress -Depth 10 } else { # category is case-sensitive so convert to Title Case $category = (Get-Culture).TextInfo.ToTitleCase($category.ToLower()) switch ($rulecontext) { both { $context = 0 } hub { $context = 1 } qmc { $context = 2 } } $json = (@{ category = $category; type = "Custom"; rule = $rule; name = $name; resourceFilter = $resourceFilter; actions = $actions; comment = $comment; disabled = $disabled.IsPresent; ruleContext = $context; tags = @(); schemaPath = "SystemRule" } | ConvertTo-Json -Compress) } return Invoke-QlikPost "/qrs/systemrule" $json } } function New-QlikStream { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$name, [string[]]$customProperties, [string[]]$tags ) PROCESS { $stream = @{ name=$name; } If( $customProperties ) { $prop = @( $customProperties | foreach { $val = $_ -Split "=" $p = Get-QlikCustomProperty -filter "name eq '$($val[0])'" @{ value = ($p.choiceValues -eq $val[1])[0] definition = $p } } ) $stream.customProperties = $prop } If( $tags ) { $prop = @( $tags | foreach { $p = Get-QlikTag -filter "name eq '$_'" @{ id = $p.id } } ) $stream.tags = $prop } $json = $stream | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost '/qrs/stream' $json } } function New-QlikTag { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$name ) PROCESS { $json = (@{ name=$name; } | ConvertTo-Json -Compress -Depth 10) return Invoke-QlikPost '/qrs/tag' $json } } function New-QlikTask { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [alias("id")] [string]$appId, [parameter(Mandatory=$true,Position=1)] [string]$name, [string[]]$tags ) PROCESS { If( $tags ) { $tagArray = @( $tags | foreach { $p = Get-QlikTag -filter "name eq '$_'" -raw @{ id = $p.id } } ) } else { $tagArray = @(); } $task = @{ task = @{ name = $name; taskType = 0; enabled = $true; taskSessionTimeout = 1440; maxRetries = 0; tags = $tagArray; app = @{ id = $appId }; isManuallyTriggered = $false; customProperties = @() }; } $json = $task | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost '/qrs/reloadtask/create' $json } } function New-QlikUser { [CmdletBinding()] param ( [string]$userId, [string]$userDirectory, [string]$name = $userId, [string[]]$roles ) PROCESS { $user = @{ userId=$userId; userDirectory=$userDirectory; name=$name } if($roles) { $user.roles = $roles } $json = $user | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost "/qrs/user" $json } } function New-QlikUserAccessGroup { [CmdletBinding()] param ( [string]$name ) PROCESS { $json = (@{ name=$name } | ConvertTo-Json -Compress -Depth 10) return Invoke-QlikPost "/qrs/License/UserAccessGroup" $json } } function New-QlikUserDirectory { [CmdletBinding()] param ( [parameter(Mandatory=$false,Position=0)] [string]$name, [parameter(Mandatory=$false,Position=1)] [string]$userDirectoryName, [ValidateSet('Repository.UserDirectoryConnectors.ODBC.OdbcSql', 'Repository.UserDirectoryConnectors.LDAP.ActiveDirectory')] [string]$type, [string]$configured=$false, [string]$syncOnlyLoggedInUsers=$true, [string]$syncStatus=0, [string]$configuredError="", [string]$operationalError="", [System.Object[]]$settings = @() ) PROCESS { $json = (@{ name=$name; userDirectoryName=$userDirectoryName; configured=$configured; operational=$false; type=$type; syncOnlyLoggedInUsers=$syncOnlyLoggedInUsers; syncStatus=$syncStatus; configuredError=$configuredError; operationalError=$operationalError; settings=$settings } | ConvertTo-Json -Compress -Depth 10) return Invoke-QlikPost "/qrs/UserDirectory" $json } } function New-QlikVirtualProxy { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$prefix, [parameter(Mandatory=$true,Position=1)] [string]$description, [parameter(Mandatory=$true,Position=2)] [alias("cookie")] [string]$sessionCookieHeaderName, [alias("authUri")] [string]$authenticationModuleRedirectUri, [alias("engine")] [string[]]$loadBalancingServerNodes = "", [alias("wsorigin")] [string[]]$websocketCrossOriginWhiteList = "" ) PROCESS { If( $loadBalancingServerNodes ) { $engines = @( $loadBalancingServerNodes | foreach { If( $_ -match $script:guid ) { @{ id = $_ } } else { $eid = Get-QlikNode -filter "hostname eq '$_'" @{ id = $eid.id } } } ) } else { $engines = @() } $json = (@{ prefix=$prefix; description=$description; authenticationModuleRedirectUri=$authenticationModuleRedirectUri; loadBalancingServerNodes=$engines; sessionCookieHeaderName=$sessionCookieHeaderName; websocketCrossOriginWhiteList=$websocketCrossOriginWhiteList; } | ConvertTo-Json -Compress -Depth 10) return Invoke-QlikPost "/qrs/virtualproxyconfig" $json } } function Publish-QlikApp { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string]$id, [parameter(Mandatory=$true,Position=1)] [string]$stream, [string]$name ) PROCESS { If( $stream -match $script:guid ) { $streamId = $stream } else { $streamId = $(Get-QlikStream -filter "name eq '$stream'").id } $path = "/qrs/app/$id/publish?stream=$streamId" If( $name ) { $path += "&name=$name" } return Invoke-QlikPut $path } } function Publish-QlikObject { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0,ValueFromPipelinebyPropertyName=$True)] [string]$id ) PROCESS { $path = "/qrs/app/object/$id/publish" return Invoke-QlikPut $path } } function Register-QlikNode { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$hostname = $($env:computername), [string]$name = $hostname, [string]$nodePurpose, [string[]]$customProperties, [string[]]$tags, [alias("engine")] [switch]$engineEnabled, [alias("proxy")] [switch]$proxyEnabled, [alias("scheduler")] [switch]$schedulerEnabled, [alias("printing")] [switch]$printingEnabled ) PROCESS { If( !$psBoundParameters.ContainsKey("hostname") ) { $psBoundParameters.Add( "hostname", $hostname ) } If( !$psBoundParameters.ContainsKey("name") ) { $psBoundParameters.Add( "name", $name ) } $password = New-QlikNode @psBoundParameters $postParams = @{__pwd="$password"} Invoke-WebRequest -Uri "http://localhost:4570/certificateSetup" -Method Post -Body $postParams -UseBasicParsing > $null } } function Remove-QlikApp { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/app/$id" } } function Remove-QlikCustomProperty { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/custompropertydefinition/$id" } } function Remove-QlikDataConnection { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/dataconnection/$id" } } function Remove-QlikRule { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/systemrule/$id" } } function Remove-QlikStream { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/stream/$id" } } function Remove-QlikTag { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/tag/$id" } } function Remove-QlikTask { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/task/$id" } } function Remove-QlikUser { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/user/$id" } } function Remove-QlikUserDirectory { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/userdirectory/$id" } } function Remove-QlikVirtualProxy { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/virtualproxyconfig/$id" } } function Remove-QlikExtension { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$ename ) PROCESS { return Invoke-QlikDelete "/qrs/extension/name/$ename" } } function Restore-QlikSnapshot { [CmdletBinding()] param () PROCESS { return Invoke-QlikPost "/qrs/sync/snapshot/restore" } } function Select-QlikApp { [CmdletBinding()] param ( #[parameter(Position=0)] #[string]$id, [string]$filter #[switch]$full, #[switch]$raw ) PROCESS { $path = "/qrs/selection/app" #If( $id ) { $path += "/$id" } #If( $full ) { $path += "/full" } return Invoke-QlikPost "$path?$filter" } } function Set-QlikLicense { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$serial, [parameter(Mandatory=$true,Position=1)] [string]$control, [parameter(Mandatory=$true,Position=2)] [string]$name, [parameter(Mandatory=$true,Position=3)] [alias("org")] [string]$organization, [parameter(Mandatory=$false,Position=4)] [string]$lef ) PROCESS { $resource = "/qrs/license?control=$control" $json = @{ serial = $serial; name = $name; organization = $organization; lef = $lef; } | ConvertTo-Json Invoke-QlikPost $resource $json return $result } } function Start-QlikTask { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [switch]$wait ) PROCESS { $path = "/qrs/task" If( $wait ) { $sync = "/synchronous" } If( $id -match($script:guid) ) { return Invoke-QlikPost "/qrs/task/$id/start$sync" } else { return Invoke-QlikPost "/qrs/task/start$($sync)?name=$id" } } } function Switch-QlikApp { [CmdletBinding()] param ( # ID of the app that is used to replace another app [parameter(Mandatory=$true,Position=0,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string]$id, # ID of the app to be replaced [parameter(Mandatory=$true,Position=1)] [string]$appId ) PROCESS { return Invoke-QlikPut "/qrs/app/$id/replace?app=$appId" } } function Sync-QlikUserDirectory { [CmdletBinding()] param ( [System.Guid[]]$guid = @() ) PROCESS { $json = ConvertTo-Json -Compress -Depth 10 $guid return Invoke-QlikPost "/qrs/userdirectoryconnector/syncuserdirectories" $json } } function Unpublish-QlikObject { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0,ValueFromPipelinebyPropertyName=$True)] [string]$id ) PROCESS { $path = "/qrs/app/object/$id/unpublish" return Invoke-QlikPut $path } } function Update-QlikApp { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$name, [string]$description, [string[]]$customProperties, [string[]]$tags ) PROCESS { $app = Get-QlikApp $id -raw If( $name ) { $app.name = $name } If( $description ) { $app.description = $description } If( $customProperties ) { $prop = @( $customProperties | foreach { $val = $_ -Split "=" $p = Get-QlikCustomProperty -filter "name eq '$($val[0])'" -raw @{ value = ($p.choiceValues -eq $val[1])[0] definition = $p } } ) $app.customProperties = $prop } If( $tags ) { $prop = @( $tags | foreach { $p = Get-QlikTag -filter "name eq '$_'" @{ id = $p.id } } ) $app.tags = $prop } $json = $app | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/app/$id" $json } } function Update-QlikCustomProperty { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$name, [string]$valueType = "Text", [string[]]$choiceValues, [ValidateSet("App","ContentLibrary","DataConnection","EngineService","Extension","ProxyService","ReloadTask","RepositoryService","SchedulerService","ServerNodeConfiguration","Stream","User","UserSyncTask","VirtualProxyConfig", IgnoreCase=$false)] [string[]]$objectTypes ) PROCESS { $prop = Get-QlikCustomProperty $id -raw if( $name ) { $prop.name = $name } if( $valueType ) { $prop.valueType = $valueType } if( $choiceValues ) { $prop.choiceValues = $choiceValues } if( $objectTypes ) { $prop.objectTypes = $objectTypes } $json = $prop | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/custompropertydefinition/$id" $json } } function Update-QlikDataConnection { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$ConnectionString ) PROCESS { $qdc = Get-QlikDataConnection -raw $id $qdc.connectionstring = $ConnectionString $json = $qdc | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/dataconnection/$id" $json } } function Update-QlikEngine { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [ValidateSet("IgnoreMaxLimit", "SoftMaxLimit", "HardMaxLimit")] [string]$workingSetSizeMode, [ValidateRange(0,100)] [Int]$workingSetSizeLoPct, [ValidateRange(0,100)] [Int]$workingSetSizeHiPct, [ValidateRange(0,100)] [Int]$cpuThrottlePercentage, [Bool]$AllowDataLineage, [Bool]$StandardReload, [string]$documentDirectory, [Int]$documentTimeout, [int]$autosaveInterval, [int]$genericUndoBufferMaxSize ) PROCESS { $engine = Get-QlikEngine -Id $id -raw Write-Verbose $workingSetSizeMode if( $workingSetSizeMode ) { switch ($workingSetSizeMode) { IgnoreMaxLimit { $sizeMode = 0 } SoftMaxLimit { $sizeMode = 1 } HardMaxLimit { $sizeMode = 2 } } $engine.settings.workingSetSizeMode = $sizeMode } if($workingSetSizeLoPct) { $engine.settings.workingSetSizeLoPct = $workingSetSizeLoPct } if($workingSetSizeHiPct) { $engine.settings.workingSetSizeHiPct = $workingSetSizeHiPct } if($cpuThrottlePercentage) { $engine.settings.cpuThrottlePercentage = $cpuThrottlePercentage } if($documentDirectory) { $engine.settings.documentDirectory = $documentDirectory } if($AllowDataLineage) { $engine.settings.allowDataLineage = $AllowDataLineage } if($StandardReload) { $engine.settings.standardReload = $StandardReload } if($documentTimeout) { $engine.settings.documentTimeout = $documentTimeout } if($autosaveInterval) { $engine.settings.autosaveInterval = $autosaveInterval } if($genericUndoBufferMaxSize) { $engine.settings.genericUndoBufferMaxSize = $genericUndoBufferMaxSize } $json = $engine | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut -Path "/qrs/engineservice/$id" -Body $json } } function Update-QlikNode { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$name, [ValidateSet("Production", "Development", "Both")] [string]$nodePurpose, [string[]]$customProperties, [string[]]$tags, [switch]$engineEnabled, [switch]$proxyEnabled, [switch]$schedulerEnabled, [switch]$printingEnabled ) PROCESS { $node = Get-QlikNode $id -raw If( $name ) { $node.name = $name } If( $nodePurpose ) { switch($nodePurpose) { Production { $node.nodePurpose = 0 } Development { $node.nodePurpose = 1 } Both { $node.nodePurpose = 2 } } } If( $customProperties ) { $prop = @( $customProperties | foreach { $val = $_ -Split "=" $p = Get-QlikCustomProperty -filter "name eq '$($val[0])'" @{ value = ($p.choiceValues -eq $val[1])[0] definition = $p } } ) $node.customProperties = $prop } If( $tags ) { $node.tags = $tags } If( $psBoundParameters.ContainsKey("engineEnabled") ) { $node.engineEnabled = $engineEnabled.IsPresent } If( $psBoundParameters.ContainsKey("proxyEnabled") ) { $node.proxyEnabled = $proxyEnabled.IsPresent } If( $psBoundParameters.ContainsKey("schedulerEnabled") ) { $node.schedulerEnabled = $schedulerEnabled.IsPresent } If( $psBoundParameters.ContainsKey("printingEnabled") ) { $node.printingEnabled = $printingEnabled.IsPresent } $json = $node | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/servernodeconfiguration/$id" $json } } function Update-QlikObject { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$owner, [bool]$approved ) PROCESS { $obj = Get-QlikObject $id -raw If( $owner ) { $obj.owner = @{id=$owner} } If( $psBoundParameters.ContainsKey("approved") ) { $obj.approved = $approved } $json = $obj | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/app/object/$id" $json } } function Update-QlikProxy { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [ValidateRange(1,65536)] [Int]$ListenPort, [Bool]$AllowHttp, [ValidateRange(1,65536)] [Int]$UnencryptedListenPort, [ValidateRange(1,65536)] [Int]$AuthenticationListenPort, [Bool]$KerberosAuthentication, [ValidateRange(1,65536)] [Int]$UnencryptedAuthenticationListenPort, [String]$SslBrowserCertificateThumbprint, [ValidateRange(1,300)] [Int]$KeepAliveTimeoutSeconds, [ValidateRange(512,131072)] [Int]$MaxHeaderSizeBytes, [ValidateRange(20,1000)] [Int]$MaxHeaderLines, [ValidateRange(1,65536)] [Int]$RestListenPort ) PROCESS { $proxy = Get-QlikProxy -raw -Id $id if ($listenPort) { $proxy.settings.listenPort = $listenPort } $proxy.settings.allowHttp = $allowHttp if ($unencryptedListenPort) { $proxy.settings.unencryptedListenPort = $unencryptedListenPort } if ($authenticationListenPort) { $proxy.settings.authenticationListenPort = $authenticationListenPort } $proxy.settings.kerberosAuthentication = $kerberosAuthentication if ($unencryptedAuthenticationListenPort) { $proxy.settings.unencryptedAuthenticationListenPort = $unencryptedAuthenticationListenPort } if ($sslBrowserCertificateThumbprint) { $proxy.settings.sslBrowserCertificateThumbprint = $sslBrowserCertificateThumbprint } if ($keepAliveTimeoutSeconds) { $proxy.settings.keepAliveTimeoutSeconds = $keepAliveTimeoutSeconds } if ($maxHeaderSizeBytes) { $proxy.settings.maxHeaderSizeBytes = $maxHeaderSizeBytes } if ($maxHeaderLines) { $proxy.settings.maxHeaderLines = $maxHeaderLines } if ($restListenPort) { $proxy.settings.restListenPort = $restListenPort } $json = $proxy | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/proxyservice/$id" $json } } function Update-QlikRule { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$name, [ValidateSet("License","Security","Sync")] [string]$category, [string]$rule, [alias("filter")] [string]$resourceFilter, [ValidateSet("hub","qmc","both")] [alias("context")] [string]$rulecontext = "both", [int]$actions, [string]$comment, [switch]$disabled ) PROCESS { switch ($rulecontext) { both { $context = 0 } hub { $context = 1 } qmc { $context = 2 } } $systemrule = Get-QlikRule $id -raw If( $name ) { $systemrule.name = $name } If( $rule ) { $systemrule.rule = $rule } If( $resourceFilter ) { $systemrule.resourceFilter = $resourceFilter } If( $category ) { $systemrule.category = $category } If( $rulecontext ) { $systemrule.rulecontext = $context } If( $actions ) { $systemrule.actions = $actions } If( $comment ) { $systemrule.comment = $comment } If( $psBoundParameters.ContainsKey("disabled") ) { $systemrule.disabled = $disabled.IsPresent } $json = $systemrule | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/systemrule/$id" $json } } function Update-QlikScheduler { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [ValidateSet("master","slave","both")] [alias("type")] [string]$schedulerServiceType, [ValidateRange(1,256)] [Int]$maxConcurrentEngines, [ValidateRange(10,10080)] [Int]$engineTimeout ) PROCESS { $scheduler = Get-QlikScheduler $id Write-Verbose $schedulerServiceType If( $schedulerServiceType -ne $null ) { switch ($schedulerServiceType) { master { $sched_type = 0 } slave { $sched_type = 1 } both { $sched_type = 2 } } $scheduler.settings.schedulerServiceType = $sched_type } if($maxConcurrentEngines) { $scheduler.settings.maxConcurrentEngines = $maxConcurrentEngines } if($engineTimeout) { $scheduler.settings.engineTimeout = $engineTimeout } $json = $scheduler | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/schedulerservice/$id" $json } } function Update-QlikReloadTask { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [Bool]$Enabled, [ValidateRange(1,2147483647)] [Int]$TaskSessionTimeout, [ValidateRange(0,20)] [Int]$MaxRetries, [string[]]$Tags ) PROCESS { $task = Get-QlikReloadTask -Id $id -Params $params $task.enabled = $Enabled $task.taskSessionTimeout = $TaskSessionTimeout $task.maxRetries = $MaxRetries If ($tags) { $task.tags = @(GetTags $tags) } $json = $task | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut -Path "/qrs/reloadtask/$id" -Body $json } } function Update-QlikServiceCluster { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelinebyPropertyName=$true,Position=0)] [Guid] $id, [string] $name, [int] $persistenceType, [int] $persistenceMode, [string] $rootFolder, [string] $appFolder, [string] $staticContentRootFolder, [string] $connector32RootFolder, [string] $connector64RootFolder, [string] $archivedLogsRootFolder, [int] $failoverTimeout ) process { $cluster = Get-QlikServiceCluster $id -raw $sp = $cluster.settings.sharedPersistenceProperties if ($name) { $cluster.name = $name } if ($persistenceType) { $cluster.settings.persistenceType = $persistenceType } if ($persistenceMode) { $cluster.settings.persistenceMode = $persistenceMode } if ($rootFolder) { $sp.rootFolder = $rootFolder } if ($appFolder) { $sp.appFolder = $appFolder } if ($staticContentRootFolder) { $sp.staticContentRootFolder = $staticContentRootFolder } if ($connector32RootFolder) { $sp.connector32RootFolder = $connector32RootFolder } if ($connector64RootFolder) { $sp.connector64RootFolder = $connector64RootFolder } if ($archivedLogsRootFolder) { $sp.archivedLogsRootFolder = $archivedLogsRootFolder } if ($failoverTimeout) { $sp.failoverTimeout = $failoverTimeout } $json = $cluster | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut /qrs/ServiceCluster/$id $json } } function Update-QlikUser { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string[]]$customProperties, [string[]]$tags, [string]$name, [string[]]$roles ) PROCESS { $user = Get-QlikUser $id -raw If( $roles ) { $user.roles = $roles } If( $name ) { $user.name = $name } If( $customProperties ) { $user.customProperties = @(GetCustomProperties $customProperties) } If( $tags ) { $user.tags = GetTags $tags } $json = $user | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/user/$id" $json } } function Update-QlikUserDirectory { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$name, [string]$path, [string]$username, [string]$password, [string]$ldapFilter, [int]$timeout, [Int]$pageSize ) PROCESS { $ud = Get-QlikUserDirectory -Id $id -raw if($name) { $ud.name = $name } if($path) { ($ud.settings | ? name -eq path).value = $path } if($username) { ($ud.settings | ? name -eq 'User name').value = $username } if($password) { ($ud.settings | ? name -eq password).value = $password } if($ldapFilter) { ($ud.settings | ? name -eq 'LDAP Filter').value = $ldapFilter } if($timeout) { ($ud.settings | ? name -eq 'Synchronization timeout in seconds').value = $timeout } if($pageSize) { ($ud.settings | ? name -eq 'Page size').value = $pageSize } $json = $ud | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut -Path "/qrs/userdirectory/$id" -Body $json } } function Update-QlikVirtualProxy { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0)] [string]$id, [string]$prefix, [string]$description, [alias("cookie")] [string]$sessionCookieHeaderName, [alias("authUri")] [string]$authenticationModuleRedirectUri, [alias("winAuthPattern")] [string]$windowsAuthenticationEnabledDevicePattern, [parameter(ValueFromPipeline=$True)] [alias("engine")] [string[]]$loadBalancingServerNodes, [alias("wsorigin")] [string[]]$websocketCrossOriginWhiteList, [String]$additionalResponseHeaders, [Int]$anonymousAccessMode, [String]$magicLinkHostUri, [String]$magicLinkFriendlyName ) PROCESS { $proxy = Get-QlikVirtualProxy -raw $id If( $prefix ) { $proxy.prefix = $prefix } If( $description ) { $proxy.description = $description } If( $sessionCookieHeaderName ) { $proxy.sessionCookieHeaderName = $sessionCookieHeaderName } If( $psBoundParameters.ContainsKey("authenticationModuleRedirectUri") ) { $proxy.authenticationModuleRedirectUri = $authenticationModuleRedirectUri } If( $psBoundParameters.ContainsKey("websocketCrossOriginWhiteList") ) { $proxy.websocketCrossOriginWhiteList = $websocketCrossOriginWhiteList } If( $psBoundParameters.ContainsKey("additionalResponseHeaders") ) { $proxy.additionalResponseHeaders = $additionalResponseHeaders } If( $psBoundParameters.ContainsKey("anonymousAccessMode") ) { $proxy.anonymousAccessMode = $anonymousAccessMode } If( $psBoundParameters.ContainsKey("windowsAuthenticationEnabledDevicePattern") ) { $proxy.windowsAuthenticationEnabledDevicePattern = $windowsAuthenticationEnabledDevicePattern } If( $psBoundParameters.ContainsKey("loadBalancingServerNodes") ) { $engines = @( $loadBalancingServerNodes | foreach { If( $_ -match $script:guid ) { @{ id = $_ } } else { $eid = Get-QlikNode -filter "hostname eq '$_'" If( $eid ) { @{ id = $eid.id } } } } ) $proxy.loadBalancingServerNodes = $engines } If( $psBoundParameters.ContainsKey("magicLinkHostUri") ) { $proxy.magicLinkHostUri = $magicLinkHostUri } If( $psBoundParameters.ContainsKey("magicLinkFriendlyName") ) {$proxy.magicLinkFriendlyName = $magicLinkFriendlyName } $json = $proxy | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/virtualproxyconfig/$id" $json } } function Wait-QlikExecution { [CmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True,Position=0,ParameterSetName="Execution")] [alias("value")] [string]$executionId, [parameter(Mandatory=$true,ValueFromPipelinebyPropertyName=$True,Position=0,ParameterSetName="Task")] [alias("id")] [string]$taskId ) PROCESS { if ($executionId) { $execution = Invoke-QlikGet "/qrs/executionSession/$executionId" $resultId = $execution.executionResult.Id $taskName = $execution.reloadTask.name } else { $task = Invoke-QlikGet "/qrs/reloadTask/$taskId" $resultId = $task.operational.lastExecutionResult.id $taskName = $task.name } do { # Get task status $rawOutput = $true $result = Invoke-QlikGet "/qrs/executionResult/$resultId" # Get internal task status code $taskstatuscode = $result.status $result = FormatOutput($result) Write-Progress -Activity $taskName -Status $result.status -CurrentOperation ($result.details | select -Last 1).message # Wait for 1 second, in a Production setting this should be set much higher to avoid stressing the QRS API Start-Sleep -Seconds 1 } until ($taskstatuscode -gt 3) #status code of more than 3 is a completion (both success and fail) return $result } } function Set-QlikCentral { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikPost "/qrs/failover/tonode/$id" } } function Update-QlikOdag { [cmdletBinding()] param ( [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelinebyPropertyName=$true,Position=0)] [Bool]$enabled, [int]$maxConcurrentRequests ) PROCESS { $rawOutput = $true $id = $(Invoke-QlikGet "/qrs/odagservice").id $odag = Invoke-QlikGet "/qrs/odagservice/$id" $odag.settings.enabled = $enabled If ( $maxConcurrentRequests ) { $odag.settings.maxConcurrentRequests = $maxConcurrentRequests } $json = $odag | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPut "/qrs/odagservice/$id" $json } } function New-QlikContentLibrary { [CmdletBinding()] param ( [parameter(Mandatory=$true,Position=0)] [string]$name, [string[]]$customProperties, [string[]]$tags ) PROCESS { $stream = @{ name=$name; } If( $customProperties ) { $prop = @( $customProperties | foreach { $val = $_ -Split "=" $p = Get-QlikCustomProperty -filter "name eq '$($val[0])'" @{ value = ($p.choiceValues -eq $val[1])[0] definition = $p } } ) $stream.customProperties = $prop } If( $tags ) { $prop = @( $tags | foreach { $p = Get-QlikTag -filter "name eq '$_'" @{ id = $p.id } } ) $stream.tags = $prop } $json = $stream | ConvertTo-Json -Compress -Depth 10 return Invoke-QlikPost '/qrs/contentlibrary' $json } } function Remove-QlikContentLibrary { [CmdletBinding()] param ( [parameter(Position=0,ValueFromPipelinebyPropertyName=$true)] [string]$id ) PROCESS { return Invoke-QlikDelete "/qrs/contentlibrary/$id" } } Export-ModuleMember -function Add-Qlik*, Connect-Qlik, Copy-Qlik*, Export-Qlik*, Get-Qlik*, Import-Qlik*, Invoke-Qlik*, New-Qlik*, Publish-Qlik*, Register-Qlik*, Remove-Qlik*, Restore-Qlik*, Select-Qlik*, Set-Qlik*, Start-Qlik*, Switch-Qlik*, Sync-QlikUserDirectory, Unpublish-Qlik*, Update-Qlik*, Wait-Qlik* -alias * |