{"id":1018,"date":"2021-01-31T19:19:28","date_gmt":"2021-01-31T18:19:28","guid":{"rendered":"http:\/\/www.vatland.no\/?p=1018"},"modified":"2021-03-24T09:22:53","modified_gmt":"2021-03-24T08:22:53","slug":"use-get-tenantlicsindb-after-syncing-them-to-our-local-db","status":"publish","type":"post","link":"https:\/\/www.vatland.no\/index.php\/use-get-tenantlicsindb-after-syncing-them-to-our-local-db\/","title":{"rendered":"Use get-tenantlicsindb after syncing them to our local db."},"content":{"rendered":"<p>Ok, Now that we have syncronized our customers licenes to a local DB, we have this new commandlet to list them. This is a easy one, no advanced tokens setup to connect to Microsoft endpoint, only local database.<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:435px;height:300px;\"><div class=\"text codecolorer\">function get-tenantlics {<br \/>\n&nbsp; &nbsp; &lt;#<br \/>\n&nbsp; .SYNOPSIS<br \/>\n&nbsp; List tenant licenses from your CSP<br \/>\n&nbsp; .DESCRIPTION<br \/>\n&nbsp; List licenses for tenant purchased using your CSP<br \/>\n&nbsp; Tenant refer to the display name of the tenant &quot;Super Company 1&quot;<br \/>\n&nbsp; Tenant is a dynamic parameter, autocomplete list.<br \/>\n<br \/>\n&nbsp; DYNAMIC PARAMTERS<br \/>\n&nbsp; <br \/>\n&nbsp; PARAMETER tenant<br \/>\n&nbsp; -tenant &lt;string&gt;<br \/>\n&nbsp; tenant refers to the display name of the tenant &quot;Super Company 1&quot;<br \/>\n&nbsp; If omitted all tenants are returned. Autocomplete list of all tenants in csp<br \/>\n<br \/>\n&nbsp; &nbsp;PARAMETER ProductName<br \/>\n&nbsp; -ProductName &lt;string&gt;<br \/>\n&nbsp; Poductname refers to Microsoft product name , &quot;Office 365 E3&quot; , this is a autocomplete field from all products in database-<br \/>\n&nbsp; .EXAMPLE<br \/>\n&nbsp; get-tenantlics -tenant 'Tenant name' -productname 'Office 365 E3' -lastndays 2<br \/>\n<br \/>\n&nbsp; .PARAMETER lastndays<br \/>\n&nbsp; Return license report for last N days, default is last reported. &nbsp;<br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp;#&gt;<br \/>\n&nbsp; &nbsp; [CmdletBinding()]<br \/>\n&nbsp; &nbsp; param(<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; [int]$lastndays = 1<br \/>\n&nbsp; &nbsp; )<br \/>\n&nbsp; &nbsp; DynamicParam {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $ParameterName = &quot;tenant&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; # Create and set the parameters' attributes<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $ParameterAttribute.Mandatory = $false<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $ParameterAttribute.Position = 1<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; # Add the attributes to the attributes collection<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $AttributeCollection.Add($ParameterAttribute)<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; # Generate and set the ValidateSet<br \/>\n&nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; # Add the ValidateSet to the attributes collection &nbsp; <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $SQLInstance = &quot;localhost\\SQLExpress&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $SQLDatabase = &quot;Microsoft365&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $sqlqr = &quot;select * from [Microsoft365].[dbo].[tenants]&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $customers = invoke-sqlcmd -query $sqlqr -ServerInstance $SQLInstance -Database $SQLDatabase<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; #$arrSet = Get-WmiObject Win32_Service -ComputerName $computername | select -ExpandProperty Name<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($Customers | Select-Object -ExpandProperty tenantname)<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $AttributeCollection.Add($ValidateSetAttribute)<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Parameter2Name = &quot;ProductName&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Parameter2Attribute = New-Object System.Management.Automation.ParameterAttribute<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Parameter2Attribute.Mandatory = $false<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Parameter2Attribute.Position = 2<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Attribute2Collection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Attribute2Collection.Add($Parameter2Attribute)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $sqlqr2 = &quot;select * from [Microsoft365].[dbo].[skus]&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $skus = invoke-sqlcmd -query $sqlqr2 -ServerInstance $SQLInstance -Database $SQLDatabase<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; #$arrSet = Get-WmiObject Win32_Service -ComputerName $computername | select -ExpandProperty Name<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $ValidateSet2Attribute = New-Object System.Management.Automation.ValidateSetAttribute($skus | Select-Object -ExpandProperty productname)<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Attribute2Collection.Add($ValidateSet2Attribute)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $RuntimeParameter2 = New-Object System.Management.Automation.RuntimeDefinedParameter($Parameter2Name, [string], $Attribute2Collection)<br \/>\n<br \/>\n<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; # Create and return the dynamic parameter<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $RuntimeParameterDictionary.Add($Parameter2Name, $RuntimeParameter2)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; return $RuntimeParameterDictionary<br \/>\n&nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; begin {<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; # Bind the parameter to a friendly variable<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Kunde = $PsBoundParameters[$ParameterName]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; if ( -not $kunde) {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $kunde = &quot;%&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; else {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Product = $PsBoundParameters[$Parameter2Name]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; if ( -not $Product) {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $Product = &quot;%&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; else {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; <br \/>\n&nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; process {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $lastndays--<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; if ($lastndays -lt 0) { $lastndays = 0 }<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $SQLInstance = &quot;localhost\\SQLExpress&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $SQLDatabase = &quot;Microsoft365&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $today = get-date -Hour 0 -Minute 0 -Second 0<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $fromdate = $today.AddDays(($lastndays * -1) )<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $sqlqr = &quot;select Date,Tenantname,Displayname,ProductName,ActiveUnits,ConsumedUnits,AvailableUnits,SuspendedUnits,TotalUnits,CapabilityStatus from [Microsoft365].[dbo].[skuscustomer] where tenantname like '$($kunde)' and Date &gt;='$($fromdate)' and Productname like '$($product)'&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $Skus = invoke-sqlcmd -query $sqlqr -ServerInstance $SQLInstance -Database $SQLDatabase<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; if (-not $skus) {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $fromdate = $today.AddDays(($lastndays * -1) - 1)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $sqlqr = &quot;select Date,Tenantname,Displayname,ProductName,ActiveUnits,ConsumedUnits,AvailableUnits,SuspendedUnits,TotalUnits,CapabilityStatus from [Microsoft365].[dbo].[skuscustomer] where tenantname like '$($kunde)' and Date &gt;='$($fromdate)' and Productname like '$($product)'&quot;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $Skus = invoke-sqlcmd -query $sqlqr -ServerInstance $SQLInstance -Database $SQLDatabase &nbsp; &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; $skus<br \/>\n&nbsp; &nbsp; }<br \/>\n}<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Ok, Now that we have syncronized our customers licenes to a local DB, we have this new commandlet to list them. This is a easy one, no advanced tokens setup to connect to Microsoft endpoint, only local database. function get-tenantlics { &nbsp; &nbsp; &lt;# &nbsp; .SYNOPSIS &nbsp; List tenant licenses from your CSP &nbsp; .DESCRIPTION &hellip; <a href=\"https:\/\/www.vatland.no\/index.php\/use-get-tenantlicsindb-after-syncing-them-to-our-local-db\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Use get-tenantlicsindb after syncing them to our local db.<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Use get-tenantlicsindb after syncing them to our local db.","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[72,73,74,2,48,10],"tags":[],"class_list":["post-1018","post","type-post","status-publish","format-standard","hentry","category-azure","category-azure-uncategorized","category-csp","category-development","category-powershell","category-windows"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"jetpack-related-posts":[{"id":975,"url":"https:\/\/www.vatland.no\/index.php\/log-tenants-from-office-365-to-local-db\/","url_meta":{"origin":1018,"position":0},"title":"Log tenants from office 365 to local Db","author":"Atle","date":"January 3, 2021","format":false,"excerpt":"Hi, I like to keep control of how many licenses our cutomers use versus how many\u00a0 have been purchased. Here is 1st part\u00a0 my PS script to copy the info from csp to the DB. I will start creating a database and table to keep a list of all the\u2026","rel":"","context":"In &quot;Azure&quot;","block_context":{"text":"Azure","link":"https:\/\/www.vatland.no\/index.php\/category\/azure\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":899,"url":"https:\/\/www.vatland.no\/index.php\/csp-access-to-tenants-using-powershell-part-2\/","url_meta":{"origin":1018,"position":1},"title":"CSP access to tenants using powershell. Part 2","author":"Atle","date":"September 20, 2019","format":false,"excerpt":"In part 1 we created the Azure Enterprise App for Partnercenter and used this information to connect using powershell and connect-partnercenter. Now we will use this to connect to one of our customers tenants. First we will use AZ module and connect-azaccount. We will use the AZ module and the\u2026","rel":"","context":"In &quot;Azure&quot;","block_context":{"text":"Azure","link":"https:\/\/www.vatland.no\/index.php\/category\/azure\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":804,"url":"https:\/\/www.vatland.no\/index.php\/use-powershell-to-get-leakedcredentials-from-azure-using-graph\/","url_meta":{"origin":1018,"position":2},"title":"Use Powershell to get LeakedCredentials from Azure using Graph","author":"Atle","date":"November 1, 2018","format":false,"excerpt":"Leaked credentials listed from Azure using powershell and Microsoft Graph\u00a0We need one Azure AD Premium X license to get this log. Would it be nice to list all leakedcredentials using powershell?(or riskysignins or identiyriskevents). All of this could be achieved using powershell and REST api at Microsoft Graph. I have\u2026","rel":"","context":"In \"Powershell\"","block_context":{"text":"Powershell","link":"https:\/\/www.vatland.no\/index.php\/tag\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.vatland.no\/wp-content\/uploads\/2018\/11\/Leaked.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.vatland.no\/wp-content\/uploads\/2018\/11\/Leaked.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.vatland.no\/wp-content\/uploads\/2018\/11\/Leaked.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":902,"url":"https:\/\/www.vatland.no\/index.php\/csp-access-to-tenants-using-powershell-part-3\/","url_meta":{"origin":1018,"position":3},"title":"CSP access to tenants using powershell. Part 3","author":"Atle","date":"September 23, 2019","format":false,"excerpt":"In this part 3 of CSP and powershell I will show how you can connect to azureAD of a customer tenant using your CSP app credentials and refreshtoken. This is almost the same procedure as we use to connect to az. We will start with the same variables as in\u2026","rel":"","context":"In &quot;Azure&quot;","block_context":{"text":"Azure","link":"https:\/\/www.vatland.no\/index.php\/category\/azure\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":875,"url":"https:\/\/www.vatland.no\/index.php\/csp-access-to-tenants-using-powershell-part-1\/","url_meta":{"origin":1018,"position":4},"title":"CSP access to tenants using powershell. Part 1","author":"Atle","date":"September 18, 2019","format":false,"excerpt":"A short explanation of how to access customer tenant using a CSP tenant SPN credential connectiong to AzureAD and AZ. Have been struggling for a while to manage all our customers tenants using powershell scripts. It can be complicated to organize all the credentials, tenant domain, tenant id's password expiry.\u2026","rel":"","context":"In &quot;Azure&quot;","block_context":{"text":"Azure","link":"https:\/\/www.vatland.no\/index.php\/category\/azure\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":914,"url":"https:\/\/www.vatland.no\/index.php\/csp-access-to-tenants-using-powershell-part-4\/","url_meta":{"origin":1018,"position":5},"title":"CSP access to tenants using powershell. Part 4","author":"Atle","date":"September 24, 2019","format":false,"excerpt":"This is a small script that connects to partnercenter list all customers tenants and let you select one. When one is selected it connects to azuread and az for that customer. All my credentials are stored in SecretServer . I use a web service request to get those credentials. I\u2026","rel":"","context":"In &quot;Azure&quot;","block_context":{"text":"Azure","link":"https:\/\/www.vatland.no\/index.php\/category\/azure\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/posts\/1018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/comments?post=1018"}],"version-history":[{"count":3,"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/posts\/1018\/revisions"}],"predecessor-version":[{"id":1038,"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/posts\/1018\/revisions\/1038"}],"wp:attachment":[{"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/media?parent=1018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/categories?post=1018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vatland.no\/index.php\/wp-json\/wp\/v2\/tags?post=1018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}