The start of 2021 brings a new logo to cloudstep, as we start to refresh our look. Our previous logo had served us well, but with the help of our friends at Skella & Co. we have been on a mission to improve our product, user experience and brand identity.
Our first logo was created before the application had launched. The new logo is an evolution of our first logo with the ‘cloud’ component and the inclusion of ‘steps’.
I’ve spent 15 years deploying on-premises versions of Microsoft Unified Communications, namely OCS, Lync & Skype for Business. During that period I did a lot of installations, but never had I done a full removal of the product. I guess that speaks to the usability of Microsoft Voice solutions. Once your in, the years just roll by like a good marriage. All good things must come to an end, now with Teams being purely cloud based no schema objects need to remain in Active Directory.
When attempting to do the final cleanup steps of the environment I was getting the following output when attempting Disable-CSAdDomain:
Disable-CsAdDomain : DomainUnprepareTask execution failed on an unrecoverable error.
At line:1 char:1
+ CategoryInfo : InvalidOperation: (:SourceCollection) [Disable-CsAdDomain], DeploymentException
+ FullyQualifiedErrorId : TaskFailed,Microsoft.Rtc.Management.Deployment.UnprepareDomainCmdlet
WARNING: Disable-CsAdDomain encountered errors. Consult the log file for a detailed analysis, and ensure all errors (2)
and warnings (0) are addressed before continuing.
The HTML report presented me with some red:
Error: Cannot remove the Active Directory settings for the domain due to “FE” still being activated.
I had a few hours of scratching my head. I’d fully un-installed the Skype for Business Server software (minus the administrative tools) from the last Front End in the environment. Even the CMS had been deleted, so why did it think it was still active?! No CMS, means no jersey for a Front End server. I waited for domain replication but still no change.
The secret is to remove the last Front End server computer object from the domain. Install the tools on something else and re-run the cmdlet. Simple, but not obvious.
Thanks to Michael for the bright idea on this one.
The key permissions outlined in the prerequisites at point 3 are:
A virtual network.
A Windows virtual machine in the virtual network.
The following required roles:
Reader role on the virtual machine.
Reader role on the NIC with private IP of the virtual machine.
Reader role on the Azure Bastion resource.
Ports: To connect to the Windows VM, you must have the following ports open on your Windows VM:
Inbound ports: RDP (3389)
My scenario is to invite a guest AAD account, add them to a group and grant the group access as per below:
Grant Contributor role to the resource group that has the VM’s for the application.
Grant Reader role to the resource group that has the Bastion host.
This way the guest user logs into the Azure Portal complying with our conditional access policy and then they are presented with only the resources they have read or higher access too. In this scenario that is the two resource groups outlined above.
The guest user locates the virtual machine they wish to connect and then chooses Connect > Bastion > UseBastion the following error message is presented.
“Unable to query Bastion data”
Initially working with Microsoft support we found that granting reader access at the subscription level gave the user permission to in-act the Bastion service, which simply give a username and password input.
These permissions were too lacks as a workaround and exposed a lot of production data to accounts that didn’t really have any business looking at it.
[12/11/2020] The case is on-going inside Microsoft and I will leave a definitive response when I get the information. I’ve done some further investigation what would be the least amount of additional ‘Reader‘ permissions are required. I’ve found the following permissions are required in my scenario:
Reader permissions on the Virtual Network that has the ‘AzureBastionSubnet‘ subnet.
Reader permissions on the Virtual Network that has the connected virtual machine network interface.
In my scenario, the virtual machines are located in a development Virtual Network that is peered with the production Virtual Network which has the subnet ‘AzureBastionHost‘. So I had two sets of permissions to add. After applying the permissions you may need to get a coffee and return to the portal as it took 5-10 minutes to kick in for me.
Hope this helps someone that has done some googling but is still scratching their head with this error message.
Getting restore points out of Azure can be like getting blood from a stone. The portal likes to always set a custom filter showing only ~90 days and your Powershell cmdlet only allows for a 30 day interval for retrieval dates. When running ‘Get-AzRecoveryServicesBackupRecoveryPoint’ you get the following:
Get-AzRecoveryServicesBackupRecoveryPoint : Time difference should not be more than 30 days
Sigh.. I just want all my restore points for a virtual machine please! All of them, because its my butt if for some reason I don’t have them. Using something like this can be useful to audit your backups against business needs for data retention.
Example: Get recovery points from the last two years for a single VM
Working with one of your customers this week who is implementing Azure API Management alongside their web applications. We are funnelling all the request logs into an Application Insights services to manage visibility of the end-to-end transaction data. We noticed that all the client GET requests had ‘0.0.0.0’ in Client IP Address.
Client IP address
Update ApplicationInsightsComponentProperties value DisableIpMasking
As this value only seems to be exposed through the API we have to either push a new incremental ARM template through the sausage maker or perform a API request directly. An API request seems like the quicker request method, but doing this in a script with authentication and correct structure takes time. I have a nice trick when wanting to update or add a value to an object when either of those feel like overkill.
You will be shown the JSON definition of your Application Insights Object. You can tell this by the line:
To know your in the right place, under properties there will be many values, we should see Application_Type, InstrumentationKey, ConnectionString, Retention, but what will be missing is DisableIpMasking. So it’s as simple as adding it.
Up the top of the page toggle the blue switch to ‘Read/Write’ from ‘Read Only’.
Remember to add a ‘,’ to the previous last line (in my case “HockeyAppToken“) before adding your new property.
The final step is to use the PUT button to update the object. Which intern has authenticated you to the API using your existing login token, constructed the JSON object and is sending a ‘POST’ method to the API endpoint for ‘management.azure.com/subscriptions/<subscriptionId>/resourceGroups/<rgName>/providers/microsoft.insights/components/<resourceName>?api-version=2015-05-01‘. Much simpler than doing a Powershell or Bash script, what a clever little tool it is.
The result will be that new request in Application Insights will have the source NAT IP address. Unfortunately all previous requests will remain scrubbed with ‘0.0.0.0’.
This is a great way to tweak services while attempting to understand whether it’s the correct knob to turn in the Azure service. But while it’s quick, it isn’t documented. If you have a repository of deployment ARM templates make sure you go back and amend the deployment JSON. The day will come when it gets re-deployed and it wont come out the sausage maker the same. The finger will get pointed back at that Azure administrator who doesn’t follow good DevOps practices.