Visual Studio Code unins000.exe Access denied

Hi All,

This week i was surprised with the following Error Message when Visual Studio Code, tried to update to the newest version.


So i've checked the Permissions
C:\Users\%username%\AppData\Local\Programs

The User don't had "Change" Permissions on the Directory


I've pushed the Permissions to the Subdirectorys and Files below.


After that, the Upgrade or Installation of Visual Studio Code was flawless




Regards
Andres


Rename UPN of specific Mailbox Types

Hi All,

Recently i had a customer where the Room Mailboxes had still the Active Directory UPN Suffix.
But that needed to Change in Order to align with Exchange Hybrid / Exchange Online.



So i did write a small PowerShell Script to fix that

The Script can also be found at my GitHub Repo

###############################################################################
# Rename UPN from specific Mailbox Type
# 11.04.2022 V0.1 - Andres Bohren - Initial Version
###############################################################################
$Rooms = Get-Mailbox -RecipientTypeDetails RoomMailbox -Resultsize Unlimited
Foreach ($Room in $Rooms)
{
    $Email = $Room.PrimarySMTPAddress
    $Alias = $Room.Alias
    $UPN = $Room.UserPrincipalName
    Write-Host "Working on: $Email / $UPN" -ForegroundColor Green
    If ($UPN -match "corp.icewolf.ch")
    {
        Write-Host "Match found"
        $NewUPN = $UPN.Replace("corp.icewolf.ch","icewolf.ch")
        Write-Host "NewUPN: $NewUPN"
        Set-Mailbox -Identity $UPN -UserPrincipalName $NewUPN
    }
}




Regards
Andres Bohren


UserCallingSettings in Microsoft Teams Admin Center (TAC)

Hi All,

Since a few days you can view and set the UserCallingSettings in Microsoft Teams Admin Center (TAC).
It seems that the "if unanswered" (VoiceMail in my case) Setting is not yet represented correctly.


Teams Client > Settings > Calls


Connect-MicrosoftTeams
Get-CsUserCallingSettings -Identity a.bohren@icewolf.ch



Regards
Andres Bohren


You can't use TenantAllowBlockList when connected to Security and Compliance

Hi All,

Recently i was stumbling across a weird behaviour regarding Exchange Online Protection (EOP) with TenantAllowBlockListItems.

Get-TenantAllowBlockListItems

Connect-ExchangeOnline
Get-TenantAllowBlockListItems -ListType Url -Block
Get-TenantAllowBlockListItems -ListType Url -ListSubType AdvancedDelivery



Represented with the following Command
Get-TenantAllowBlockListItems -ListType Url -Block


Advanced Delivery - Represented with the following Command
Get-TenantAllowBlockListItems -ListType Url -ListSubType AdvancedDelivery


Then i connected to Security and Compliance

Connect-IPPSSession
Get-TenantAllowBlockListItems -ListType Url

Error:
Das Format des in den Parameter objectId eingegebenen Werts ist ungültig. Prüfen Sie den Wert, und versuchen Sie es erneut.
Parameter name: objectId
    + CategoryInfo          : NotSpecified: (:) [Get-TenantAllowBlockListItems], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.Exchange.Management.SystemConfigurationTasks.TenantAllowBlock
   List.GetTenantAllowBlockListItems
    + PSComputerName        : che01b.ps.compliance.protection.outlook.com


Get-TenantAllowBlockListItems -ListType Url -ListSubType AdvancedDelivery

Error:
A parameter cannot be found that matches parameter name 'ListSubType'.
    + CategoryInfo          : InvalidArgument: (:) [Get-TenantAllowBlockListItems], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Get-TenantAllowBlockListItems
    + PSComputerName        : che01b.ps.compliance.protection.outlook.com



As soon as you're connected to  https://ps.compliance.protection.outlook.com you will get the above error Messages

Get-PSSession
Get-PSSession | fl



Regards
Andres Bohren


M365 group-based License (step-by-step)

Hi All,

Most Organizations i know use M365 group-based Licensing.
It fit's theyr provisioning Processes because it's just adding a User to another Active Directory Group. As they are already used to do.

What is group-based licensing in Azure Active Directory?

Licensing requirements
You must have one of the following licenses for every user who benefits from group-based licensing:
  • Paid or trial subscription for Azure AD Premium P1 and above
  • Paid or trial edition of Microsoft 365 Business Premium or Office 365 Enterprise E3 or Office 365 A3 or Office 365 GCC G3 or Office 365 E3 for GCCH or Office 365 E3 for DOD and above


Or go directly to Azure AD Licensing Overview

Select "All products"


Select the License and click on "+ Assign"


Now select "+ Add users an groups" and select the synchronized Group from Azure Active directory


If you want enable only a subset of the Licenses you can switch them "Off or On"



Now the Licenses are assigned direct (in the M365 Admin Portal) and via Group


I remove the checkbox at the License


Now the License is only applied via Group - aka group-based License.


In the M365 Admin Portal the License is now greyed out - and you see the Info that it's assigned via group-based License



Regards
Andres Bohren


Extract M365 Licensing GUID's and Product names from MS Website

Hi All,

For a Project i wanted to Extract the M365 License and ServicePlan Guids from the Website below

Product names and service plan identifiers for licensing


The whole Script is published at my GitHub Repo

Why not using PowerShell for that

$URI = "https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference"
$WebRequest = Invoke-WebRequest -URI $URI
$WebRequest | get-member


As you can see, with PowerShell 7 the Property "ParsedHtml" is missing. It somehow has a dependency to the local installed Browser. So you can't use it on Azure Automation :(

$URI = "https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference"
$WebRequest = Invoke-WebRequest -URI $URI
$WebRequest | get-member


You can get the same behavior, wen using the UseBasicParsing Parameter.

$URI = "https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference"
$WebRequest = Invoke-WebRequest -URI $URI -UseBasicParsing
$WebRequest | get-member


I found this Function to convert a HTML Table - but it relies on that ParsedHtml Attribute


$tables = @($WebRequest.ParsedHtml.getElementsByTagName("TABLE"))
$table = $tables[0]
$MSServicePlan = ConvertFrom-HTMLTable $table
$MSServicePlan[0]


$MSServicePlan | ft "GUID","String ID","Product Name"


$MSServicePlan |  Export-CSV -Path "C:\Temp\licensing-service-plan.csv" -Encoding UTF8 -NoTypeInformation



Regards
Andres Bohren


Use Set/Remove-CsPhoneNumberAssignment in MicrosoftTeams

Hi all,

I hope you all have already seen the Change in M365 Message Center for assigning Teams Phone Number





But there are also other Requirements before adding a Phone Number in Teams:
  • The User must have a valid Teams License assigned
  • The User must have a Teams Phone (PhoneSystem/MCOEV) License assigned
We can check that with the Microsoft.Graph PowerShell Module

#Get License from User
Connect-MgGraph -Scopes User.ReadWrite.All
$Licenses = Get-MgUserLicenseDetail -UserId a.bohren@icewolf.ch
$Licenses
$Licenses[0].ServicePlans


To check the Licenses use this Code

#Teams License
$Licenses | where {$_.ServicePlans.ServicePlanname -match "TEAMS1"}

#PhoneSystem
$Licenses | where {$_.SkuId -eq "e43b5b99-8dfb-405f-9987-dc307f34bcbd"}



If you need to Add a License use this Code

###############################################################################
# Add PhoneSystem / MCOEV License
###############################################################################
Set-MgUserLicense -UserId m.muster@icewolf.ch -AddLicenses @{SkuId = 'e43b5b99-8dfb-405f-9987-dc307f34bcbd'} -RemoveLicenses @() #PhoneSystem / MCOEV




Now let's check the CsUser

###############################################################################
# Get-CsOnlineUser
# https://docs.microsoft.com/en-us/powershell/module/skype/get-csonlineuser?view=skype-ps
###############################################################################
Connect-MicrosoftTeams
Get-CsOnlineUser -Identity m.muster@icewolf.ch | fl EnterpriseVoiceEnabled, *HostingProvider, HostedVoiceMail, *um*, *LineUri



Assign the Number

###############################################################################
# Set-CsPhoneNumberAssignment
# https://docs.microsoft.com/en-us/powershell/module/teams/set-csphonenumberassignment?view=teams-ps
###############################################################################
Set-CsPhoneNumberAssignment -Identity m.muster@icewolf.ch -PhoneNumber +41215553975 -PhoneNumberType DirectRouting
Get-CsOnlineUser -Identity m.muster@icewolf.ch | fl EnterpriseVoiceEnabled, *HostingProvider, HostedVoiceMail, *um*, *LineUri


If you want to remove the Number

###############################################################################
# Remove-CsPhoneNumberAssignment
# https://docs.microsoft.com/en-us/powershell/module/teams/remove-csphonenumberassignment?view=teams-ps
###############################################################################
Remove-CsPhoneNumberAssignment -Identity m.muster@icewolf.ch -RemoveAll
Get-CsOnlineUser -Identity m.muster@icewolf.ch | fl EnterpriseVoiceEnabled, *HostingProvider, HostedVoiceMail, *um*, *LineUri


It's good Practice to also remove the TeamsPhone (PhoneSystem / MCOEV ) License

###############################################################################
# Remove PhoneSystem / MCOEV License
###############################################################################
Set-MgUserLicense -UserId m.muster@icewolf.ch -AddLicenses @() -RemoveLicenses @('e43b5b99-8dfb-405f-9987-dc307f34bcbd') #PhoneSystem / MCOEV




If you don't wait long enough, between the Assignment of the PhoneSystem License and Set-MgUserLicense you will get this Error:

Code: BadRequest
Message:The user '<ID' already has a telephone number set in the on-premises Active Directroy and synchronized...



I did write a Function to set and Remove the TeamsPhone Number including adding and removing the PhoneSystem License.

You can find the Code in my GitHub Repo

Connect-MicrosoftTeams
Connect-MgGraph -Scopes User.ReadWrite.All
Set-TeamsPhoneNumber -UPN m.muster@icewolf.ch -PhoneNumber "+41215553975" -PhoneNumberType "DirectRouting"



Connect-MicrosoftTeams
Connect-MgGraph -Scopes User.ReadWrite.All
Remove-TeamsPhoneNumber -UPN m.muster@icewolf.ch



Function Set-TeamsPhoneNumber
{
    Param(
        [Parameter(Mandatory=$true)][String]$UPN,
        [Parameter(Mandatory=$true)][String]$PhoneNumber,
        [Parameter(Mandatory=$true)][String]$PhoneNumberType
    )   
    
    #Check Licenses of User
    $Licenses = Get-MgUserLicenseDetail -UserId $UPN

    #Check Teams License
    $TeamsLicense = $Licenses | where {$_.ServicePlans.ServicePlanname -match "TEAMS1"}
    If ($Null -eq $TeamsLicense)
    {
        Throw "User has no Teams License"
    }

    #Check PhoneSystem
    $PhoneSystemLicense = $Licenses | where {$_.SkuId -eq "e43b5b99-8dfb-405f-9987-dc307f34bcbd"} #PhoneSystem / MCOEV
    If ($Null -eq $PhoneSystemLicense)
    {
        Write-Host "Adding PhoneSystem License" -ForeGroundColor Green
        Set-MgUserLicense -UserId $UPN -AddLicenses @{SkuId = 'e43b5b99-8dfb-405f-9987-dc307f34bcbd'} -RemoveLicenses @() | Out-Null #PhoneSystem / MCOEV
    } else {
        Write-Host "PhoneSystem License found"
        [Bool]$NoWait = $true
    }

    Do
    {
        $Licenses = Get-MgUserLicenseDetail -UserId $UPN
        $PhoneSystemLicense = $Licenses | where {$_.SkuId -eq "e43b5b99-8dfb-405f-9987-dc307f34bcbd"} #PhoneSystem / MCOEV
        If ($Null -eq $PhoneSystemLicense)
        {
            Write-Host "No PhoneSystem License found" -ForeGroundColor Yellow
        }
        Start-Sleep -Seconds 5
    } while ($Null -eq $PhoneSystemLicense)
    
    If ($NoWait -eq $true)
    {
        #Do Nothing
    } else {
        Write-Host "Wait 120 Seconds before assigning Number"
        Start-Sleep -Seconds 120
    }

    ###############################################################################
    # Set-CsPhoneNumberAssignment
    # https://docs.microsoft.com/en-us/powershell/module/teams/set-csphonenumberassignment?view=teams-ps
    ###############################################################################
    Set-CsPhoneNumberAssignment -Identity $UPN -PhoneNumber $PhoneNumber -PhoneNumberType $PhoneNumberType

}

Function Remove-TeamsPhoneNumber
{
    Param(
        [Parameter(Mandatory=$true)][String]$UPN
    )


    $CsUser = Get-CsOnlineUser -Identity m.muster@icewolf.ch
    If ($CsUser.EnterpriseVoiceEnabled -eq $True)
    {
        ###############################################################################
        # Remove-CsPhoneNumberAssignment
        # https://docs.microsoft.com/en-us/powershell/module/teams/remove-csphonenumberassignment?view=teams-ps
        ###############################################################################
        Remove-CsPhoneNumberAssignment -Identity $UPN -RemoveAll
       
        #Remove PhoneSystem / MCOEV License
        Write-Host "Remove PhoneSystem / MCOEV License"
        Set-MgUserLicense -UserId $UPN -AddLicenses @() -RemoveLicenses @('e43b5b99-8dfb-405f-9987-dc307f34bcbd') | Out-Null
    } else {
        Write-Host "EnterpriseVoiceEnabled is already False"
    }
}

###############################################################################
# Main Script
###############################################################################
Connect-MicrosoftTeams
Connect-MgGraph -Scopes User.ReadWrite.All
Set-TeamsPhoneNumber -UPN m.muster@icewolf.ch -PhoneNumber "+41215553975" -PhoneNumberType "DirectRouting"
Get-CsOnlineUser -Identity m.muster@icewolf.ch | fl EnterpriseVoiceEnabled, HostingProvider, *LineUri, *tel*
Remove-TeamsPhoneNumber -UPN m.muster@icewolf.ch




Regards
Andres Bohren


Deploy Azure SQL Database with ARM Template (Part 3)

Hi All,

Finally i have some time to do a Project i've always wanted to do.
In a Series of Blog Article i will create a SQL Server / SQL Database in Azure and compare diffrent Deployment Methods.

Let's start with an ARM Template.
First i started creating a SQL Database in the Azure Portal. Under "Review + create" you can download the Template.



The Template consists of a template.json and parameters.json



This Script is also available on my GitHub Repo

###############################################################################
# Demo03-SQLDB-ARM.ps1
# Create SQL Server / Firewall Rule / SQL Database with ARM Template (JSON)
# 05.04.2022 - Initial Version - Andres Bohren
###############################################################################

###############################################################################
# Connect AzAccount
###############################################################################
Connect-AzAccount

###############################################################################
# Set Subscription
###############################################################################
Set-AzContext [SubscriptionID/SubscriptionName]

###############################################################################
# New-AzDeployment (Create ResourceGroup)
# https://docs.microsoft.com/en-us/powershell/module/az.resources/new-azdeployment?view=azps-7.4.0
###############################################################################
$TemplateFile = "https://raw.githubusercontent.com/BohrenAn/GitHub_PowerShellScripts/main/Azure/Demo03-ResourceGroup-Template.json"
$ParameterFile = "https://raw.githubusercontent.com/BohrenAn/GitHub_PowerShellScripts/main/Azure/Demo03-ResourceGroup-Parameters.json"
New-AzDeployment -TemplateFile $TemplateFile -TemplateParameterFile $ParameterFile -Location "westeurope"





Now it's time to create the SQL Server Object, the Firewall Rules and the Database

###############################################################################
# New-AzResourceGroupDeployment (Create SQL Server / Database / Firewall Rules)
# https://docs.microsoft.com/en-us/powershell/module/az.resources/new-azresourcegroupdeployment?view=azps-7.4.0
###############################################################################

$Securestring = ConvertTo-SecureString "SloppyJoe!" -AsPlainText -Force
$TemplateFile = "https://github.com/BohrenAn/GitHub_PowerShellScripts/blob/main/Azure/Demo03-SQLDB-Template.json"
$ParameterFile = "https://github.com/BohrenAn/GitHub_PowerShellScripts/blob/main/Azure/Demo03-SQLDB-Parameters.json"
$ResourceGroup = "RG_Demo03"
New-AzResourceGroupDeployment -ResourceGroupName $ResourceGroup -TemplateFile $TemplateFile -TemplateParameterFile $ParameterFile -administratorLoginPassword $Securestring






As you can see the SQL Server has been created in the right Resourcegroup.
All the Settings like MinimumTLSVersion and Firewall Rules are set



The Database has been created with the correct SKU



Cleanup and delete the Resource Group

###############################################################################
# Remove-AzResourceGroup
# https://docs.microsoft.com/en-us/powershell/module/az.resources/remove-azresourcegroup?view=azps-7.4.0
###############################################################################
$ResourceGroup = "RG_Demo03"
Remove-AzResourceGroup -Name $ResourceGroup -Force

If you prefer to deploy with Azure CLI here you go

###############################################################################
# Deployment using Azure CLI
###############################################################################
az login



$TemplateFile = "https://raw.githubusercontent.com/BohrenAn/GitHub_PowerShellScripts/main/Azure/Demo03-ResourceGroup-Template.json"
$ParameterFile = "https://raw.githubusercontent.com/BohrenAn/GitHub_PowerShellScripts/main/Azure/Demo03-ResourceGroup-Parameters.json"
az deployment sub create --template-uri $TemplateFile --parameters $ParameterFile --location "westeurope"



$Securestring = ConvertTo-SecureString "SloppyJoe!" -AsPlainText -Force
$TemplateFile = "https://raw.githubusercontent.com/BohrenAn/GitHub_PowerShellScripts/main/Azure/Demo03-SQLDB-Template.json"
$ParameterFile = "https://raw.githubusercontent.com/BohrenAn/GitHub_PowerShellScripts/main/Azure/Demo03-SQLDB-Parameters.json"
$ResourceGroup = "RG_Demo03"
az deployment group create --resource-group $ResourceGroup --template-uri $TemplateFile --parameters $ParameterFile administratorLoginPassword=$Securestring



###############################################################################
#Cleanup
###############################################################################
$ResourceGroup = "RG_Demo03"
az group delete --resource-group $ResourceGroup --yes


Regards
Andres Bohren


Deploy Azure SQL Database with AZ CLI (Part 2)

Hi All,

Finally i have some time to do a Project i've always wanted to do.
In a Series of Blog Article i will create a SQL Server / SQL Database in Azure and compare diffrent Deployment Methods.

Let's start with the AZ CLI











The Script can also be found on my GitHub Repo

###############################################################################
# Demo02-SQLDB-Az.ps1
# Create SQL Server / Firewall Rule / SQL Database with AZ CLI
# 05.04.2022 - Initial Version - Andres Bohren
###############################################################################

###############################################################################
# Login with AzureCLI
###############################################################################
az login





###############################################################################
# Create Demo Resource Group
# https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest#az-group-create
###############################################################################
$ResourceGroup = "RG_Demo02"
$Location = "westeurope"
az group create --location $Location --name $ResourceGroup




###############################################################################
# Create SQL Server Object
# https://docs.microsoft.com/en-us/cli/azure/sql/server?view=azure-cli-latest#az-sql-server-create
###############################################################################
$SQLServerName = "icewolfsqldemo02"
$AdminUser = "sqladmin"
$AdminPassword = "SloppyJoe!"
$MinimalTLSVersion = "1.2"
az sql server create --location $Location --resource-group $ResourceGroup --name $SQLServerName --admin-user $AdminUser --admin-password $AdminPassword --minimal-tls-version $MinimalTLSVersion




###############################################################################
# Create SQL Server FirewallRule
# https://docs.microsoft.com/en-us/cli/azure/sql/server/firewall-rule?view=azure-cli-latest#az-sql-server-firewall-rule-create
###############################################################################
#Create SQL Server Firewall Rule for Azure
az sql server firewall-rule create -g $ResourceGroup -s $SQLServerName -n Azure --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
#Create SQL Server Firewall Rule for Icewolf
$RuleName = "IcewolfPublicIP"
$StartIpAddress = "95.143.60.18"
$EndIpAddress = "95.143.60.18"
az sql server firewall-rule create -g $ResourceGroup -s $SQLServerName -n $RuleName --start-ip-address $StartIpAddress --end-ip-address $EndIpAddress




As you can see the SQL Server has been created in the right Resourcegroup.
All the Settings like MinimumTLSVersion and Firewall Rules are set




###############################################################################
# Create SQL Database in Azure
###############################################################################
$DatabaseName = "db_demo02"
$Edition = "Basic"
az sql db create --resource-group $ResourceGroup --server $SQLServerName --name $DatabaseName --zone-redundant $false --edition $Edition




The Database has been created with the correct SKU



Finally we need to clean up and delete the Demo Resource Group

###############################################################################
#Cleanup
###############################################################################
$ResourceGroup = "RG_Demo02"
az group delete --resource-group $ResourceGroup --yes




Regards
Andres Bohren