Use PowerShell DSC and Azure Automation to Create an Active Directory Domain

Because of the recent domain change of my blog, I decided to completely start over again with my lab in Azure. I’ve been working with Desired State Configuration Configs in Azure for quite a few years, but never used them for my own lab environment. It felt a bit overkill to do that, but now I wanted to start over and do everything right.

This step-by-step installation guide explains how to create a DSC Configuration in Azure Automation and how to apply this on your domain controller in Azure.

Continue reading “Use PowerShell DSC and Azure Automation to Create an Active Directory Domain”

Update Windows 10 with SCCM/WSUS only by defeating Dual Scan

With Windows 10 1607, Microsoft introduced Dual Scan functionality, which allows the computer to connect with Microsoft Updates besides using WSUS or SCCM. Steve Henry from Microsoft: “It is for the enterprise that wants WU to be its primary update source while Windows Server Update Services (WSUS) provides all other content.” I’ve seen various blog posts not covering all the steps I had to take to ensure Windows only looks to SCCM/WSUS. Especially covering Windows 10 deployments with System Center – Configuration Manager.

Continue reading “Update Windows 10 with SCCM/WSUS only by defeating Dual Scan”

PowerShell – Signed scripts “cannot be loaded because running scripts is disabled”

So you are signing your PowerShell scripts as a Best Practice from Microsoft. Good job! You’ve configured the PowerShell Execution Policy as AllSigned and you’ve created an application in SCCM where you run the signed script as:

PowerShell.exe -File .\Script.ps1

The application installs just fine on your machine from the Software Center. During the Task Sequence, the application cannot be installed and in the Event Viewer. You’ll find the following error message:

PowerShell.exe: File <Filename> cannot be loaded because running scripts is disabled on this system. For more information, see about_execution_policies at…”

You open up PowerShell to see the current ExecutionPolicy. “Get-ExecutionPolicy -List” shows that all scopes have undefined execution policies. With “Get-Help about_Execution_Policies” you find out that Undefined policy is equal to a restricted policy and that “Permits individual commands, but will not run scripts”.

The solution

Go back to your application in SCCM and make sure you set the ExecutionPolicy to AllSigned so it will work both during a Task Sequence and while working in OS.

PowerShell.exe -ExecutionPolicy AllSigned -File .\Script.ps1

Cheers!

Create a Hyper-V NAT Switch with PowerShell – the easy way

You can follow the original guide by Microsoft and manually edit all the details, or just use the variables from the script below and let PowerShell do the work for you.
# Variables
$InternalSwitchName = "Internal Virtual Switch"
$NATGatewayPrefixLength = "24"
$NATGatewayNetwork = "192.168.0.0/$NATGatewayPrefixLength"
$NATGatewayIP = "192.168.0.1"
$NATNetworkName = "NAT Network"

# Create the VM Switch and NAT Gateway
New-VMSwitch -SwitchName $InternalSwitchName -SwitchType Internal
New-NetIPAddress -IPAddress $NATGatewayIP -PrefixLength $NATGatewayPrefixLength -InterfaceIndex (Get-NetAdapter -Name $("vEthernet ($InternalSwitchName)")).InterfaceIndex
New-NetNat -Name $NATNetworkName -InternalIPInterfaceAddressPrefix $NATGatewayNetwork

PowerShell – How to Create an Array with PSObject

As I told you before in my previous blog post, I was asked to build an interactive PowerShell script for creating Virtual Machines in Azure. In this blog post, I want to show you how I’ve created a report (or array) within PowerShell that:

  • Visualize the to-be-created objects to the user
  • Allows PowerShell to get the data of that array to create Virtual Machines. This makes sure that you have a consistent view of what PowerShell will create for you. See it as an order overview before you buy something online.

Let’s imagine I have all the Virtual Machines that I want to create in $VMs. This can be an import of a CSV, or maybe I’ve asked the user for details with “Read-Host” or Out-GridView. When you import a CSV, the content will already be organized in an array. But with this code, you can easily add more content to it and combine both data from a CSV and from the script. For example, a randomized password or the first available IP address in a subnet in Azure. My end goal is to have a nice overview of all the needed Virtual Machines in $Report, which I can later use to make those VMs. With the code below, you will create a PSObject for every VM in the $VMs variable. After the PSObject has been created, it will append to the $Report variable. With “$Report = @()” you ask PowerShell to create an empty array. See it as an empty table that you could later use to add content to it. After the deployment has succeeded or failed, you can add the status to $VM.DeploymentStatus.

# Set report variable
$Report = @()

Foreach ($VM in $VMs) {
    $PSObject = New-Object PSObject -Property @{
        DeploymentName          = $VM.resourceGroupName + "-" + (Get-Date -Format "yyyyMMdd-hh-mm-ss")
        VMName                  = $VM.vmName
        Location                = $VM.resourceGroupLocation
        ResourceGroupName       = $VM.resourceGroupName
        AdminPassword           = $VM.adminPassword
        VMSize                  = $VM.vmSize
        VirtualNetwork          = $VM.virtualNetwork
        VirtualNetworkRG        = $VM.virtualNetwork.ResourceGroupName
        SubnetName              = $VM.subnetName
        IPAddress               = $VM.ipAddress
        OperatingSystem         = $VM.operatingSystem
        DeploymentStatus        = $Null
    }
    $Report += $PSObject
}

# Show the report
$Report

# Or show it in Table Format
# $Report | Format-Table

The above example is by far the easiest way to create a nice array for me.

Thanks for reading. Hope you find it useful too.

PowerShell – Using Out-GridView to Select a Parameter

Last week I was asked to build an interactive PowerShell script for creating Virtual Machines in Azure. In this blog post, I want to share an easy way to prompt a user for a selection.

# Select Azure subscription
$AzureSubscription = (Get-AzureRmSubscription | Out-GridView -Title &quot;Choose your Azure subscription and click OK.&quot; -PassThru)
Write-Output &quot;Switching to Azure subscription: $($AzureSubscription.Name)&quot;
$AzureSubscriptionInfo = Select-AzureRmSubscription -SubscriptionId $AzureSubscription.Id

This uses Out-GridView to display the contents of the “Get-AzureRmSubscription” Cmdlet and asks the user to make a selection. The user is able to sort and filter the contents within the grid and the user will be informed of the decision by using “Write-Output”.

Out-GridView

Let’s say it’s not the most elegant way to ask a user to select a value because it’s a pop-up and because of the small “OK” and “Cancel” buttons, but this PowerShell script was developed for IT Administrators. The benefit is that it’s easy to use with out-of-the-box code, instead of using custom modules.

That’s it for now, hope you find it useful.

Cheers!

PowerShell Function to Restart a Process

My notebook connects to a Docking Station with access to my receiver with speakerset, 2 screens, power and a KVM switch for my mouse and keyboard. When I lock my laptop, the sounds switches from the receiver to my internal speakers. When I unlock my laptop, the sound switches back but the Spotify application doesn’t play any sound. Closing the application doesn’t solve this problem, because the application will crash and I have to use the Task Manager to force the application to close. I made a PowerShell function that I’ve added to my PowerShell profile.

The Restart-Spotify function looks for any process that ends with “spotify” and stops the process. When all the processes are killed, a new instance of Spotify will be opened and the PowerShell console will close itself.

Even a reinstall of Spotify doesn’t help solving this issue I’m facing for months now. So the above script is a great workaround for me.