Install Windows Admin Center (WAC) using DSC

Windows Admin Center (WAC) is a locally deployed, browser-based app for managing servers, clusters, hyper-converged infrastructure, and Windows 10 PCs. It was previously known as Project Honolulu.

ss_wacdsc_overview

WAC really shines when being used to manage headless Windows Servers (e.g. Windows Server Core). The benefits of deploying Windows Server Core are huge, but it can be a bit daunting to system administrators that have only used the Windows GUI experience to manage servers.

It is pretty easy to install WAC, but if you want to install it with PowerShell DSC, then here is a config for you to use:

The config is parameterized and supports specifying the port for the WAC to listen on  and using either a self-signed certificate or a local machine certificate in the by specifying a thumbprint.

To apply the DSC using a self-signed certificate and on the default port of 6516, run the following in an Administrator PowerShell console:

ss_wacdsc_defaultport

You can run this on a Windows Server Core machine by logging in and typing powershell to start a PowerShell console, then entering the commands above.

To apply the DSC configuration specifying a certificate with a thumbprint from the local machine store and on Port 4000, run these commands instead:

ss_wacdsc_installwiththumbprint

This DSC configuration can also be used on Virtual Machines deployed to Azure, using either the Azure DSC Extension Handler or a Azure Automation DSC Pull Server.

Easy as all that. Now you can use the awesome WAC GUI and still run headless while also taking advantage of the benefits that DSC brings.

Advertisements

Get the ForceChangePassword Office 365 User Setting with PowerShell

Recently I was asked by a friend if I knew of a way to get the value of the setting that forces a user to change their password when the next log in to Office 365. The friend wanted to get this value for all users using PowerShell.

Changing this setting is fairly straight forward either in the Office 365 portal or using the Set-MsolUserPassword cmdlet in the MSOnline PowerShell module:

ss_o365_setmsoluserpassword

However retrieving the current value of the setting isn’t possible using Get-MoslUser cmdlet – the attribute does not appear in the returned object:

ss_o365_getmsoluser

Instead, we need to use the Get-AzureADUser cmdlet in the AzureAD PowerShell Module to query the Azure Active Directory for the Office 365 tenant.

If you don’t have the AzureAD module installed, use Install-Module cmdlet to install it from the PowerShell Gallery:

Then connect to the AzureAD using the Connect-AzureAD cmdlet. Once connected you can run the following command to get the user object and show only the appropriate property (ForceChangePasswordNextLogin of the PasswordProfile object):

ss_o365_getazureadallforcechangepasswordnextlogin

This is all fairly straight forward once you figure out which object in Azure AD contains the information required.

Disable TLS 1.0, TLS 1.1 and 3DES in Azure API Management using an ARM Template

Recently, I’ve been putting together a continuous delivery pipeline (using VSTS) for our Azure API Management service using Azure Resource Manager (ARM) templates. One of the things I needed to be able to do to secure this service properly is to disable TLS 1.0, TLS 1.1 and 3DES. This is pretty easy to do in the portal:

ss_apim_disabletls3des

However, we only allow changes to be made via our continuous delivery pipeline (a good thing by the way) then I had to change the ARM template.

Side note: Disabling TLS 1.0, TLS 1.1 and 3DES is pretty important for keeping your system secure. But if you have an Azure Application Gateway in front of your API Management service, then you’ll also need to configure the Azure Application Gateway to disable TLS 1.0 and TLS 1.1. This is done in a slightly different way, but can also be done in an ARM Template (post a comment if you’re not sure how to do this and I’ll write another post).

I found the documentation for the API Management service resource here. This shows it can be done by setting the customProperties object in the ARM Template. But the documentation isn’t completely clear.

But after a little bit of trial and error I managed to figure it out and get it working. What you need to do is add the following customProperties to the properties of the API Management service resource:

This is what the complete ARM template looks like:

Side note: the template above is based off the Azure Quickstart Template for API Management.

Hopefully you find this if you’re looking for an example of how to do this and it saves you some time.

 

Managing Users & Permissions in Cosmos DB with PowerShell

If you’re just getting started with Cosmos DB, you might not have come across users and permissions in a Cosmos DB database. However, there are certain use cases where managing users and permissions are necessary. For example, if you’re wanting to be able to limit access to a particular resource (e.g. a collection, document, stored procedure) by user.

The most common usage scenario for users and permissions is if you’re implementing a Resource Token Broker type pattern, allowing client applications to directly access the Cosmos DB database.

Side note: The Cosmos DB implementation of users and permissions only provides authorization – it does not provide authentication. It would be up to your own implementation to manage the authentication. In most cases you’d use something like Azure Active Directory to provide an authentication layer.

But if you go hunting through the Azure Management Portal Cosmos DB data explorer (or Azure Storage Explorer) you won’t find any way to configure or even view users and permissions.

ss_cdb_cosmosdbdataexplorer

To manage users and permissions you need to use the Cosmos DB API directly or one of the SDKs.

But to make Cosmos DB users and permissions easier to manage from PowerShell, I created the Cosmos DB PowerShell module. This is an open source project hosted on GitHub. The Cosmos DB module allows you to manage much more than just users and permissions, but for this post I just wanted to start with these.

Requirements

This module works on PowerShell 5.x and PowerShell Core 6.0.0. It probably works on PowerShell 3 and 4, but I don’t have any more machines running this version to test on.

The Cosmos DB module does not have any dependencies, except if you call the New-Cosmos DbContext function with the ResourceGroup parameter specified as this will use the AzureRM PowerShell modules to read the Master Key for the connection directly from your Cosmos DB account. So I’d recommend installing the Azure PowerShell modules or if you’re using PowerShell 6.0, install the AzureRM.NetCore modules.

Installing the Module

The best way to install the Cosmos DB PowerShell module is from the PowerShell Gallery. To install it for only your user account execute this PowerShell command:

Install-Module -Name CosmosDB -Scope CurrentUser

ss_cdb_cosmosdbinstallmodulecurrentuser

Or to install it for all users on the machine (requires administrator permissions):

Install-Module -Name CosmosDB

ss_cdb_cosmosdbinstallmoduleallusers

Context Variable

Update 2018-03-06

As of Cosmos DB module v2.0.1, the connection parameter has been renamed to context and the New-CosmosDbConnection function has been renamed New-CosmosDbContext. This was to be more inline with naming adopted by the Azure PowerShell project. The old connection parameters and New-CosmosDbConnection function is still available as an alias, so older scripts won’t break. But these should be changed to use the new naming if possible as I plan to deprecate the connection version at some point in the future.

This post was updated to specify the new naming, but screenshots still show the Connection aliases.

Before you get down to the process of working with Cosmos DB resources, you’ll need to create a context variable containing the information required to connect. This requires the following information:

  1. The Cosmos DB Account name
  2. The Cosmos DB Database name
  3. The Master Key for the account (you can have the Cosmos DB PowerShell module get this directly from your Azure account if you wish).

To create the connection variable we just use the New-CosmosDbContext:

ss_cdb_cosmosdbnewconnection

If you do not wish to specify your master key, you can have the New-CosmosDbContext function pull your master key from the Azure Management Portal directly:

ss_cdb_cosmosdbnewconnectionviaportal

Note: This requires the AzureRM.Profile and AzureRM.Resoures module on Windows PowerShell 5.x or AzureRM.Profile.NetCore and AzureRM.Resources.NetCore on PoweShell Core 6.0.0.

Managing Users

To add a user to the Cosmos DB Database use the New-CosmosDBUser function:

New-CosmosDbUser -Context $context -Id 'daniel'

ss_cdb_cosmosdbnewuser

To get a list of users in the database:

Get-CosmosDbUser -Context $context

ss_cdb_cosmosdbgetusers

To get a specific user:

Get-CosmosDbUser -Context $context -Id 'daniel'

ss_cdb_cosmosdbgetuser

To remove a user (this will also remove all permissions assigned to the user):

Remove-CosmosDbUser -Context $context -Id 'daniel'

ss_cdb_cosmosdbremoveuser

Managing Permissions

Permissions in Cosmos DB are granted to a user for a specific resource. For example, you could grant a user access to just a single document, an entire collection or to a stored procedure.

To grant a permission you need to provide four pieces of information:

  1. The Id of the user to grant the permission to.
  2. An Id for the permission to create. This is just string to uniquely identify the permission.
  3. The permission mode to the permission: All or Read.
  4. The Id of the resource to grant access to. This can be generated from one of the Get-CosmosDb*ResourcePath functions in the CosmosDB PowerShell module.

In the following example, we’ll grant the user daniel all access to the TestCollection:

ss_cdb_cosmosdbnewpermission

Once a permission has been granted, you can use the Get-CosmosDbPermission function to retrieve the permission and with it the Resource Token that can be used to access the resource for a limited amount of time (between 10 minutes and 5 hours).

Note: as you have the Master Key already, using the Resource Token isn’t required.

For example, to retrieve all permissions for the user with Id daniel and a resource token expiration of 600 seconds:

Get-CosmosDbPermission -Context $context -UserId 'daniel' -TokenExpiry '600' |
fl *

ss_cdb_cosmosdbgetpermission

You can as expected delete a permission by using the Remove-CosmosDbPermission function:

Remove-CosmosDbPermission -Context $context -UserId 'daniel' -Id 'AccessTestCollection'

ss_cdb_cosmosdbremovepermission

Final Thoughts

So this is pretty much all there is to managing users and permissions using the Cosmos DB PowerShell module. This module can also be used to manage the following Cosmos DB resources:

  • Attachments
  • Collections
  • Databases
  • Documents
  • Offers
  • Stored procedures
  • Triggers
  • User Defined Functions

You can find additional documentation and examples of how to manage these resources over in the Cosmos DB PowerShell module readme file on GitHub.

Hopefully this will help you in any Cosmos DB automation tasks you might need to implement.

 

Configure Azure SQL Server Automatic Tuning with PowerShell

One thing I’ve found with configuring Azure services using automation (e.g. Azure PowerShell Modules, Azure Resource Manager template) is that the automation features are a little bit behind the feature set. For example, the Azure PowerShell modules may not yet implement settings for new or preview features. This can be a an issue if you’re strictly deploying everything via code (e.g. infrastructure as code). But if you run into a problem like this, all is not lost. So read on for an example of how to solve this issue.

Azure REST APIs

One of the great things about Azure is that everything is configurable by making direct requests to the Azure REST APIs, even if it is not available in ARM templates or Azure PowerShell.

Depending on the feature/configuration you can sometimes use the Set-AzureRmResource cmdlets to make calls to the REST APIs. But this cmdlet is limited to using an HTTP method of POST. So if you need to use PATCH, you’ll need to find an alternate way to make the call.

So, what you need then is to use the Invoke-RestMethod cmdlet to create a custom call to the REST API. This is the process I needed to use to configure the Azure SQL Server Automatic Tuning settings and what I’ll show in my script below.

The Script

The following script can be executed in PowerShell (of course) and requires a number of parameters to be passed to it:

  • SubscriptionId – the subscription Id of the Azure subscription that contains the Azure SQL Server.
  • ResourceGroupName – The name of the resource group containing SQL Server or
    database.
  • ServerName – The name of the Azure SQL Server to set the automatic tuning
    options on.
  • DatabaseNameThe name of the Azure SQL Database to set the automatic tuning options on. If you pass this parameter then the automatic tuning settings are applied to the Azure SQL Database, not the server.
  • Mode – This defines where the settings for the automatic tuning are
    obtained from. Inherit is only valid if the DatabaseName is specified.
  • CreateIndexEnable automatic tuning for creating an index.
  • DropIndexEnable automatic tuning for dropping an index.
  • ForceLastGoodPlan – Enable automatic tuning for forcing last good plan.

Requirements: You need to have the installed the AzureRM.Profile PowerShell module (part of the AzureRM PowerShell Modules) to use this script. The script also requires you to have logged into your Azure Subscription using Add-AzureRmAccount (as a user or Service Principal).

Example Usage

To apply custom automatic tuning to an Azure SQL Server:

.\Set-AzureRMSqlServerAutotuning.ps1 -SubscriptionId '<Subscription Id>' -ResourceGroupName '<Resource Group name>' -ServerName '<Azure SQL server name>' -Mode Custom -CreateIndex On -DropIndex On -ForceLastGoodPlan Off

ss_sqlserver_serverautotuning

To apply custom automatic tuning to an Azure SQL Database:

.\Set-AzureRMSqlServerAutotuning.ps1 -SubscriptionId '<Subscription Id>' -ResourceGroupName '<Resource Group name>' -ServerName '<Azure SQL server name>' -DatabaseName '<Azure SQL database name>' -Mode Custom -CreateIndex On -DropIndex On -ForceLastGoodPlan Off

ss_sqlserver_databaseautotuning

Conclusion

I’ve not yet encountered something in Azure that I can’t configure via the Azure REST APIs. This is because the Azure Management Portal uses the same APIs – so if it is available in the portal then you can do it via the Azure REST APIs. The biggest challenge is determining the body, header and methods available if the APIs are not yet documented.

If the API you need is not documented then you can raise a question in the Microsoft Azure Forums or on Stack Overflow. Failing that you can use the developer tools in your browser of choice to watch the API calls being made to the portal – I’ve had to resort to this many times, but documenting that process is something I’ll save for another day.

 

Create a Scheduled Task with unlimited Execution Time Limit in PowerShell

When creating a scheduled task in PowerShell you may wish to set the Execution Time Limit of the task to be unlimited (no time limit).

ss_scheduledtask_executiontimelimit

This will prevent the task from being terminated if it is still running after a specific period of time.

Creating scheduled tasks using PowerShell is pretty easy using the *-ScheduledTask* cmdlets in Windows Server 2012 and above.

However, after working on this issue in the xScheduledTask DSC resource in the Microsoft DSC Resource Kit I found that there are some differences in how to do this between Windows Server 2012 R2 and Windows Server 2016.

So in this post I’m going to show how to create a scheduled task with no Execution Time Limit that will work on both Windows Server 2012 R2 (and Windows 8/8.1) and Windows Server 2016 (and Windows 10).

I’ll also show the method that works only on Windows Server 2016.

All Versions of Windows Server

To create a scheduled task with unlimited Execution Time Limit on Windows Server 2012 R2 and Windows Server 2016.

This should also work on Windows Server 2012, but I have not confirmed this. It will NOT work on Windows Server 2008 R2. It should also work on Windows 8/8.1/10.

Windows Server 2016 Only

To create a scheduled task with unlimited Execution Time Limit on Windows Server 2016 only:

This method is a more elegant approach and arguably how the Scheduled Task cmdlets are intended to be used. But you would only use this method if your task does not need to created on an operating system earlier than Windows Server 2016/Windows 10.

So, hopefully this will help anyone else out there who has struggled with this.

 

 

 

 

Auto Formatting PowerShell in Visual Studio Code

One of the features I’m most fond of in Visual Studio Code is the Format Document feature that is built into Visual Studio Code.

ss_vscode_formatdocument

Side Note: If you’re writing PowerShell scripts or modules then you should be using Visual Studio Code. You should only be using PowerShell ISE if you don’t have the ability to install Visual Studio Code.

The Format Document feature can be used in many different document types in Visual Studio Code to correct the layout based on your user settings or the workspace settings for the project you’re working on.

ss_vscode_settings

This enables me to configure Visual Studio Code to auto format PowerShell code the way I like it for my own projects, but still adhere to the code formatting standards of any other projects I work on without having to remember what they are for each. This saves so much time and hassle.

Tip: If you’re contributing code to an Open Source project, the project maintainers may have included a .vscode\settings.json in the project folder. This may contain workspace specific formatting settings that you should apply before submitting code back to the project.

But even if you’ve don’t define and code formatting settings Visual Studio Code will still do a great job of formatting your PowerShell code. Having nicely formatted code really is not a requirement to being awesome at writing PowerShell, but it does make it easier for not so awesome PowerShell people to read, understand and potentially maintain your work.

Formatting a PowerShell Script

Here are the simple instructions for auto formatting a document in Visual Studio Code:

  1. Download and install Visual Studio Code.
  2. Once Visual Studio Code is installed, add the PowerShell extension:
    ss_vscode_powershellextension
  3. In Visual Studio Code, open the folder of the project containing the file you want to format or open an individual PowerShell file (PS1, PSD1, PSM1).
    ss_vscode_powershellbadcodeformat

    Note: Workspace formatting settings are only used if you’ve opened the folder rather than an individual file.

  4. Press SHIFT+ALT+F (or press F1 and type Format and select Format Document).
    ss_vscode_powershellgoodcodeformat
  5. The code is now all well formatted, so save the document.

It really is as easy as that.

Happy formatting.