I have the following Powershell-Script I wrote, which is working fine in Powershell ISE. The problem is, I need it working in VS Code.
What is the script doing? Well, it connects to an Azure Active Directory (User with Admin-Privilegs is needed) Looks for active users, who haven't licensed Teams, Sharepoint, OneDrive AND Exchange (that was the tasks origin, to check if all four applications are NOT licensed, if one is - the user won't be listed!)
Then it looks for the license status, lists affected user in the console and offers the option to export it into an excel file.
# Install AzureAD-Module (if not installed)
if (-not (Get-Module -Name AzureAD -ListAvailable)) {
Write-Host -ForegroundColor Yellow "The AzureAD-Module isn't installed. Installation will be started..."
Install-Module -Name AzureAD -Force
}
# Connect with Azure AD
Connect-AzureAD
# Request Tenant-ID
$tenantId = (Get-AzureADTenantDetail).ObjectId
# Request Username
$currentUserName = $env:USERNAME
# Request every user without app-access
$usersWithoutAppAccess = Get-AzureADUser -All $true | Where-Object {
$userId = $_.ObjectId
$hasExchangeLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*EXCHANGE_S_*" }).Count -eq 0
$hasOneDriveLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*SHAREPOINT_S_*" }).Count -eq 0
$hasSharePointLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*SHAREPOINTENTERPRISE_*" }).Count -eq 0
$hasTeamsLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*TEAMS1_*" }).Count -eq 0
$hasExchangeLicense -and $hasOneDriveLicense -and $hasSharePointLicense -and $hasTeamsLicense
}
# Print affected user into powershell console
$affectedUserCount = $usersWithoutAppAccess.Count
Write-Host -ForegroundColor Yellow "Anzahl der Benutzer ohne App-Zugriff: $affectedUserCount"
Write-Host -ForegroundColor Yellow "Betroffene Benutzer:"
$usersWithoutAppAccess | ForEach-Object {
Write-Host $_.UserPrincipalName
# check status about license history for user
$userLicenseHistory = Get-AzureADUserLicenseDetail -ObjectId $_.ObjectId
if ($userLicenseHistory) {
Write-Host "previously allocated licenses:"
$userLicenseHistory | ForEach-Object {
Write-Host "- $_.SkuPartNumber"
}
} else {
Write-Host "There are no previously allocated licenses."
}
}
# request user with at least one license
$usersWithAppAccess = Get-AzureADUser -All $true | Where-Object {
$userId = $_.ObjectId
$hasExchangeLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*EXCHANGE_S_*" }).Count -gt 0
$hasOneDriveLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*SHAREPOINT_S_*" }).Count -gt 0
$hasSharePointLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*SHAREPOINTENTERPRISE_*" }).Count -gt 0
$hasTeamsLicense = (Get-AzureADUserLicenseDetail -ObjectId $userId | Where-Object { $_.ServicePlans -like "*TEAMS1_*" }).Count -gt 0
$hasExchangeLicense -or $hasOneDriveLicense -or $hasSharePointLicense -or $hasTeamsLicense
}
# export list ofuser without app-access and user with at least on app-license into excel (optional)
Write-Host -ForegroundColor Green "Do you wish to export the list of user without any access to any app and user with at least one app license into an excelfile? (Y/N)"
$exportToExcel = Read-Host
if ($exportToExcel -eq "Y") {
# path for excelfile
$documentsPath = [Environment]::GetFolderPath('MyDocuments')
$excelFileName = "$(Get-Date -Format 'yyyyMMdd')_UsersAccess.xlsx"
$excelFilePath = Join-Path -Path $documentsPath -ChildPath $excelFileName
# check, if file already exists
$counter = 1
while (Test-Path $excelFilePath) {
$counter++
$excelFileName = "$(Get-Date -Format 'yyyyMMdd')_UsersAccess_$counter.xlsx"
$excelFilePath = Join-Path -Path $documentsPath -ChildPath $excelFileName
}
# create object for excel table
$excel = New-Object -ComObject Excel.Application
$workbook = $excel.Workbooks.Add()
# Sheet "User without app-access"
$worksheetWithoutAppAccess = $workbook.Worksheets.Item(1)
$worksheetWithoutAppAccess.Name = "user without app-access"
# title for "user without app-access"
$worksheetWithoutAppAccess.Cells.Item(1, 1).Value2 = "Tenant-ID"
$worksheetWithoutAppAccess.Cells.Item(1, 2).Value2 = $tenantId
$worksheetWithoutAppAccess.Cells.Item(3, 1).Value2 = "UserPrincipalName"
$worksheetWithoutAppAccess.Cells.Item(3, 2).Value2 = "DisplayName"
$worksheetWithoutAppAccess.Cells.Item(3, 3).Value2 = "LicensedUser"
# format title for "User without app-access"
$headerRangeWithoutAppAccess = $worksheetWithoutAppAccess.Range("A1:C3")
$headerRangeWithoutAppAccess.Font.Bold = $true
# write data into the sheet for "User without app-access" into the file
$rowIndexWithoutAppAccess = 4
foreach ($userWithoutAppAccess in $usersWithoutAppAccess) {
$worksheetWithoutAppAccess.Cells.Item($rowIndexWithoutAppAccess, 1).Value2 = $userWithoutAppAccess.UserPrincipalName
$worksheetWithoutAppAccess.Cells.Item($rowIndexWithoutAppAccess, 2).Value2 = $userWithoutAppAccess.DisplayName
$worksheetWithoutAppAccess.Cells.Item($rowIndexWithoutAppAccess, 3).Value2 = "No"
$rowIndexWithoutAppAccess++
}
# automatically align column-width for "User without app-access"
$usedRangeWithoutAppAccess = $worksheetWithoutAppAccess.UsedRange
$usedRangeWithoutAppAccess.EntireColumn.AutoFit() | Out-Null
# sheet for "User with at least one license"
$worksheetWithAppAccess = $workbook.Worksheets.Add()
$worksheetWithAppAccess.Name = "User with app-license"
# write title for "User with app-license"
$worksheetWithAppAccess.Cells.Item(1, 1).Value2 = "Tenant-ID"
$worksheetWithAppAccess.Cells.Item(1, 2).Value2 = $tenantId
$worksheetWithAppAccess.Cells.Item(3, 1).Value2 = "UserPrincipalName"
$worksheetWithAppAccess.Cells.Item(3, 2).Value2 = "DisplayName"
$worksheetWithAppAccess.Cells.Item(3, 3).Value2 = "LicensedUser"
$worksheetWithAppAccess.Cells.Item(3, 4).Value2 = "LicensedAppCount"
$worksheetWithAppAccess.Cells.Item(3, 5).Value2 = "LicensedApps"
# format titles for "User with app-license"
$headerRangeWithAppAccess = $worksheetWithAppAccess.Range("A1:E3")
$headerRangeWithAppAccess.Font.Bold = $true
# write data for "User with app-license" into the file
$rowIndexWithAppAccess = 4
foreach ($userWithAppAccess in $usersWithAppAccess) {
$worksheetWithAppAccess.Cells.Item($rowIndexWithAppAccess, 1).Value2 = $userWithAppAccess.UserPrincipalName
$worksheetWithAppAccess.Cells.Item($rowIndexWithAppAccess, 2).Value2 = $userWithAppAccess.DisplayName
$worksheetWithAppAccess.Cells.Item($rowIndexWithAppAccess, 3).Value2 = "Yes"
$userLicenseStatus = Get-AzureADUserLicenseDetail -ObjectId $userWithAppAccess.ObjectId
if ($userLicenseStatus) {
$licensedApps = $userLicenseStatus.ServicePlans | ForEach-Object {
$_.ServicePlanName
}
$licensedAppCount = $licensedApps.Count
$worksheetWithAppAccess.Cells.Item($rowIndexWithAppAccess, 4).Value2 = [int]$licensedAppCount
$worksheetWithAppAccess.Cells.Item($rowIndexWithAppAccess, 5).Value2 = $licensedApps -join ","
}
$rowIndexWithAppAccess++
}
# automatically align column-width for "User with app-license"
$usedRangeWithAppAccess = $worksheetWithAppAccess.UsedRange
$usedRangeWithAppAccess.EntireColumn.AutoFit() | Out-Null
# save and close excel-table
$workbook.SaveAs($excelFilePath)
$workbook.Close()
# clean up excel-objects
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($worksheetWithoutAppAccess) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($worksheetWithAppAccess) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
Remove-Variable excel, workbook, worksheetWithoutAppAccess, worksheetWithAppAccess
Write-Host -ForegroundColor Green "The list was exported successfully:"
Write-Host -ForegroundColor Green $excelFilePath
} else {
Write-Host -ForegroundColor Green "The export was skipped."
}
The problem is, the Module MSOnline in VS Code isn't working as also the AzureAD Module. I found out it's possible to use the Az-Module, but I don't find any useful hints how to get any information about licensedetails, everything I tried ends in issues/errors in the console (which is btw. really annoying due to version features which were cut or changed) or I am referred to "use MSOnline etc." which isn't working.
Can someone help me please, how to change that code, so it would be working in VS Code?
Best Regards,