Skip to content

ScriptWizards.Net Posts

Featured Post

* Script Wizards *

Welcome, young sorcerers of the digital realm, to the sacred halls of ScriptWizards.Net! I am but a humble Script Wizard, a sage of the scripting arts, who has traversed the vast expanses of time and space delving into the arcane mysteries of programming. Within these digital scrolls, you shall find the eldritch secrets of PowerShell & Python, the ancient languages of automation, woven with threads of magic and logic.

Modern Azure PowerShell: Where It Still Makes Sense

Azure PowerShell never really went away, but the way it’s used has changed a lot.

If you still think of it as a provisioning tool, or something that lives in old Automation Accounts, you’re probably missing where it actually fits in modern Azure environments.

This isn’t about scripts for creating resources. It’s about operating and governing Azure safely once infrastructure already exists.

PowerShell Isn’t Competing With IaC

Terraform and Bicep are very good at declaring infrastructure.
PowerShell is very good at reasoning about what already exists.

That distinction matters.

In real-world platforms, PowerShell is usually used after deployment:

  • validating configurations
  • checking compliance
  • coordinating changes across subscriptions
  • enforcing standards that can’t be expressed cleanly as declarations

Trying to replace Terraform with PowerShell creates fragile automation.
Trying to replace PowerShell with Terraform creates blind spots.

Mature teams use both, intentionally.


Where Azure PowerShell Still Shines

PowerShell tends to show up in places where context matters.

It’s commonly used for:

  • subscription and tenant-level visibility
  • identity-aware automation using managed identities
  • guardrails that detect drift rather than constantly rewriting state
  • controlled operational changes where “just apply” would be risky

These problems are procedural by nature. PowerShell handles them well.

Why Old PowerShell Got a Bad Reputation

Most complaints about Azure PowerShell come from outdated patterns:

  • long, stateful scripts
  • manual authentication
  • hard-coded assumptions
  • automation that can’t be safely re-run

Those approaches don’t survive modern governance or security expectations.

Today, PowerShell automation is usually:

  • stateless
  • identity-first
  • read-heavy and conservative about changes
  • designed to fail safely

When used that way, it scales surprisingly well.


PowerShell vs Azure CLI: The Real Difference

Most comparisons focus on syntax or preference, but that’s not what matters in practice.

Azure CLI is optimised for direct execution. It works best when the task is clear, linear, and short-lived. That makes it a good fit for ad-hoc operations and simple automation.

PowerShell is better at reasoning about state. Its object-based approach makes it easier to inspect resources, apply conditions, and handle edge cases as automation grows more complex.

This difference becomes obvious over time. CLI scripts tend to stay small. PowerShell scripts tend to evolve into tools that are maintained by teams, not individuals.

That’s why many mature Azure environments use both: CLI for speed, PowerShell for automation that needs to last.

How to Generate Strong Passwords Using PowerShell

Creating strong, unique passwords is crucial for securing online accounts and systems. PowerShell offers a straightforward way to generate random, secure passwords.

Why Use PowerShell for Password Generation?

PowerShell provides several built-in functions and cmdlets that make it easy to generate random strings of characters. You can customise the length and composition of these strings to meet the security requirements of your organisation or personal accounts. This flexibility ensures that your passwords include a mix of letters, numbers, and special characters, adhering to best practices for password strength.

Password Generator Script:

Here’s a PowerShell script that generates a random password with a specified number of characters. The password will include uppercase letters, lowercase letters, numbers, and special characters, ensuring it is both strong and secure.

# ScriptWizards.Net Password Generator Script
# Define the length of the password
$passwordLength = 16

# Define the character sets to use in the password
$uppercaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
$lowercaseLetters = 'abcdefghijklmnopqrstuvwxyz'
$numbers = '0123456789'
$specialCharacters = '!@#$%^&*()-_=+[]{}|;:,.<>?/'

# Combine all character sets into one
$allCharacters = $uppercaseLetters + $lowercaseLetters + $numbers + $specialCharacters

# Create an empty password variable
$password = ''

# Generate a random password by selecting random characters from the combined set
for ($i = 1; $i -le $passwordLength; $i++) {
    $randomIndex = Get-Random -Minimum 0 -Maximum $allCharacters.Length
    $password += $allCharacters[$randomIndex]
}

# Output the generated password
Write-Output "Generated Password: $password"

How the Script Works

Setting Password Length: The script begins by defining the desired length of the password ($passwordLength). In this example, the password length is set to 16 characters.

Character Sets: Four character sets are defined: uppercase letters, lowercase letters, numbers, and special characters. These sets are stored as strings. If you require specific characters in your passwords (e.g., excluding certain special characters), you can easily customise the character sets.

Combining Character Sets: All character sets are concatenated into a single string ($allCharacters). This combined string serves as the pool of characters from which the random password will be generated.

Password Generation Loop: A for loop runs for the number of times specified by $passwordLength. In each iteration, the Get-Random cmdlet selects a random character from the combined character set, which is then appended to the $password string.

Output: Finally, the generated password is printed to the console using Write-Output.

Security Considerations

This script generates a password in memory, which can be accessed by other processes. For more sensitive applications, consider securely handling the password or directly passing it to the system that requires it.

Diagnosing Roaming Profile Issues with PowerShell

Roaming profiles allow users to access their personal settings and files from any computer within a Windows network. However, issues with roaming profiles can disrupt this seamless experience, leading to partial synchronisation, profile corruption, or the inability to log in properly. Diagnosing these issues can be challenging, but PowerShell offers a powerful way to automate and streamline this process.

Understanding Roaming Profile Issues

A roaming profile issue occurs when the user’s profile settings and data fail to synchronise correctly across different machines. Common symptoms include:

  • Delays or errors during login.
  • Notifications indicating partial synchronisation.
  • Missing or corrupted files and settings.

Potential causes for these issues include:

  • Network connectivity problems.
  • Insufficient permissions or storage space on the profile server.
  • Corrupted profile data.
  • Conflicts between different versions of profile data.

Diagnosing with PowerShell

PowerShell can be used to scan the Event Viewer for specific events that indicate roaming profile problems. The script below searches both the Application and System logs for events related to user profile issues, filtering for key event IDs that commonly indicate problems.

The PowerShell Script

Here’s a PowerShell script designed to diagnose roaming profile issues:

# ScriptWizards.Net Roaming Profile Diagnostic Script
# Define the event logs and the event IDs to look for
$logNames = @("Application", "System")
$eventIDs = @(1509, 1511, 1521, 1530, 1542)

# Initialise an array to collect roaming profile issues
$roamingProfileIssues = @()

# Loop through each log and retrieve the events
foreach ($logName in $logNames) {
    $events = Get-WinEvent -LogName $logName | Where-Object { $eventIDs -contains $_.Id }
    # Filter the events related to roaming profiles
    $issues = $events | Where-Object {
        ($_.Id -in $eventIDs) -and ($_.Message -match "profile")
    }
    # Add the issues to the collection
    $roamingProfileIssues += $issues
}

# Check if any issues were found and output the results
if ($roamingProfileIssues.Count -eq 0) {
    Write-Output "No roaming profile issues found."
} else {
    Write-Output "Roaming profile issues found:"
    foreach ($event in $roamingProfileIssues) {
        $details = @{
            TimeCreated = $event.TimeCreated
            LogName = $event.LogName
            EventID = $event.Id
            Message = $event.Message
        }
        $details
    }
}

Script Breakdown

  1. Define Logs and Event IDs:
    • Specifies logs to search (Application and System) and event IDs associated with profile issues (1509, 1511, 1521, 1530, 1542).
  2. Initialize Collection:
    • Creates an empty array $roamingProfileIssues to store found issues.
  3. Retrieve and Filter Events:
    • Loops through each log, retrieves events with Get-WinEvent, and filters for those with specified IDs and “profile” in the message.
  4. Output Results:
    • Outputs “No roaming profile issues found” if no issues are detected.
    • If issues are found, it provides details such as time created, log name, event ID, and message.

Conclusion

Diagnosing roaming profile issues is critical for maintaining a smooth user experience in networked environments. Using PowerShell to automate the search for relevant events in the Event Viewer simplifies this task, making it easier to identify and address problems promptly. By understanding the potential causes and using the provided script, administrators can effectively troubleshoot and resolve roaming profile issues.

How to Sign Scripts in PowerShell

PowerShell is a powerful scripting language used for task automation and configuration management across various platforms. While its versatility is one of its greatest strengths, it also introduces potential security risks, particularly when running scripts from untrusted sources. Signing PowerShell scripts is a crucial step in ensuring the integrity and authenticity of the scripts you run, thereby protecting your systems from malicious code. This guide will walk you through the process of signing PowerShell scripts.

Why Sign PowerShell Scripts?

Before diving into the how-to, it’s important to understand why script signing is essential:

  1. Security: Signing scripts helps ensure that the script has not been tampered with and is from a trusted source.
  2. Compliance: Many organisations have policies that require scripts to be signed for auditing and compliance purposes.
  3. Trust: Users can verify the identity of the script author, fostering trust in the script’s legitimacy.
  4. Execution Policy: PowerShell has various execution policies (e.g., AllSigned, RemoteSigned) that control the conditions under which scripts can run. Signing scripts is necessary to meet the requirements of stricter policies.

Prerequisites for Script Signing

Before you can sign a PowerShell script, you need:

  1. A Code Signing Certificate: This can be obtained from a trusted Certificate Authority (CA) or generated internally if your organisation uses a Public Key Infrastructure (PKI).
  2. PowerShell: Ensure you have PowerShell 5.1 or later, as it includes the necessary cmdlets for script signing.

Generating a Self-Signed Certificate

For demonstration purposes, we’ll create a self-signed certificate. In a production environment, it is recommended to use a certificate issued by a trusted CA.

Create a Self-Signed Certificate:

$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -Subject "CN=PowerShell Script Signing"

This command creates a new self-signed certificate in the current user’s certificate store with the subject “PowerShell Script Signing”.

Export the Certificate:

$certPath = "C:\path\to\cert.pfx"
$password = ConvertTo-SecureString -String "YourPassword" -Force -AsPlainText
Export-PfxCertificate -Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" -FilePath $certPath -Password $password

This exports the certificate to a .pfx file, secured with a password.

Importing the Certificate

To sign scripts, the certificate must be imported into the certificate store:

Import the Certificate:

$password = ConvertTo-SecureString -String "YourPassword" -Force -AsPlainText
Import-PfxCertificate -FilePath "C:\path\to\cert.pfx" -CertStoreLocation Cert:\CurrentUser\My -Password $password

This command imports the certificate into the current user’s personal certificate store.

Signing a PowerShell Script

With the certificate in place, you can now sign your PowerShell script:

Get the Certificate:

$cert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.Subject -eq "CN=PowerShell Script Signing" }

Sign the Script:

Set-AuthenticodeSignature -FilePath "C:\path\to\script.ps1" -Certificate $cert

This command signs the script using the specified certificate.

Verifying the Script Signature

To verify that the script is properly signed:

Check the Signature:

$signature = Get-AuthenticodeSignature -FilePath "C:\path\to\script.ps1"
$signature.Status

This command retrieves the signature information for the script. The Status property should indicate that the script is signed and valid.

Execution Policies and Script Signing

PowerShell execution policies govern the conditions under which scripts can run. The relevant policies for script signing are:

  1. AllSigned: All scripts and configuration files must be signed by a trusted publisher.
  2. RemoteSigned: Downloaded scripts must be signed by a trusted publisher.

To set an execution policy:

Set-ExecutionPolicy -ExecutionPolicy AllSigned -Scope CurrentUser

This sets the execution policy to AllSigned for the current user, ensuring that only signed scripts can run.

Conclusion

Signing PowerShell scripts is a crucial step in enhancing the security and integrity of your automation tasks. By following this guide, you can create and use certificates to sign your scripts, thereby ensuring that your scripts are from a trusted source and have not been tampered with. Remember, while self-signed certificates are useful for testing and development, always use certificates from a trusted CA for production environments.

Exploring PowerShell Arrays: A Comprehensive Guide

In programming, an array is a data structure that allows you to store multiple values in a single variable. Arrays are particularly useful for managing collections of related data. In PowerShell, an array can hold items of different types, such as numbers, strings, or even other arrays. PowerShell provides robust capabilities for handling arrays. In this guide we explore the different types of arrays in PowerShell and how to use them.

Types of Arrays in PowerShell

  • Simple Arrays
  • Multidimensional Arrays
  • Jagged Arrays
  • ArrayLists

Let’s go into detail on each type of Array:

Simple Arrays

A simple array in PowerShell is a collection of items of the same or different types. You can create an array using the @() syntax or by simply listing items separated by commas.

# Creating a simple array
$simpleArray = @(1, 2, 3, 4, 5)

# Alternative way
$simpleArray = 1, 2, 3, 4, 5

# Accessing elements
Write-Output $simpleArray[0]  # Outputs: 1

# Adding an element
$simpleArray += 6

# Display the array
$simpleArray

Multidimensional Arrays

Multidimensional arrays store data in a grid format, making them ideal for representing matrices or tables. You can create a multidimensional array using the New-Object cmdlet.

# Creating a 2x2 multidimensional array
$multiArray = New-Object 'object[,]' 2,2

# Assigning values
$multiArray[0,0] = 'A'
$multiArray[0,1] = 'B'
$multiArray[1,0] = 'C'
$multiArray[1,1] = 'D'

# Accessing elements
Write-Output $multiArray[0,1]  # Outputs: B

# Display the array
$multiArray

Jagged Arrays

Jagged arrays are arrays of arrays, where each inner array can be of different lengths. This structure provides greater flexibility compared to multidimensional arrays.

# Creating a jagged array
$jaggedArray = @()
$jaggedArray += ,@(1, 2, 3)
$jaggedArray += ,@(4, 5)
$jaggedArray += ,@(6, 7, 8, 9)

# Accessing elements
Write-Output $jaggedArray[0][1]  # Outputs: 2

# Display the array
$jaggedArray | ForEach-Object { $_ }

ArrayLists

ArrayLists, part of the .NET framework, provide dynamic arrays that can expand as needed. They offer more flexibility than simple arrays, especially when you need to perform many additions and deletions.

# Creating an ArrayList
$arrayList = [System.Collections.ArrayList]::new()

# Adding elements
$arrayList.Add(1) | Out-Null
$arrayList.Add(2) | Out-Null
$arrayList.Add(3) | Out-Null

# Accessing elements
Write-Output $arrayList[1]  # Outputs: 2

# Removing an element
$arrayList.Remove(2)

# Display the array
$arrayList

Conclusion

PowerShell arrays are powerful tools for managing collections of data. Understanding the different types of arrays—simple arrays, multidimensional arrays, jagged arrays, and ArrayLists—can enhance your scripting capabilities. Each type serves different purposes and choosing the right one depends on the specific needs of your task.

Base64 Encoding with PowerShell

Base64 encoding is a method used to encode binary data into an ASCII string format by translating it into a radix-64 representation. It is commonly used in various applications, including encoding email attachments, JSON web tokens, and data storage. This method ensures that the data remains intact without modification during transport.

PowerShell includes built-in support for base64 encoding and decoding. In this guide, we’ll explore how to perform base64 encoding in PowerShell.

What is Base64 Encoding?

Base64 encoding converts binary data into a text format using 64 different ASCII characters. These characters include uppercase letters (A-Z), lowercase letters (a-z), numbers (0-9), and two additional symbols (+ and /). This encoding is particularly useful for encoding data that needs to be safely transmitted over media that are designed to deal with textual data.

PowerShell and Base64 Encoding

PowerShell provides several ways to handle base64 encoding. The most straightforward method involves using the [Convert]::ToBase64String() method for encoding and [Convert]::FromBase64String() for decoding.

Encoding a string to Base64

Here is a PowerShell script to encode the string “ScriptWizards.net” to base64:

# Define the string to encode
$plainText = "ScriptWizards.net"

# Convert the string to a byte array
$bytes = [System.Text.Encoding]::UTF8.GetBytes($plainText)

# Encode the byte array to base64
$base64Encoded = [Convert]::ToBase64String($bytes)

# Display the base64 encoded string
Write-Output $base64Encoded

Output:

U2NyaXB0V2l6YXJkcy5uZXQ=

Conclusion

PowerShell, with its robust scripting capabilities, provides straightforward methods for performing base64 encoding and decoding.

By utilising the [System.Text.Encoding]::UTF8.GetBytes() method to convert a string into a byte array and [Convert]::ToBase64String() to encode it, PowerShell allows for efficient and effective data encoding. This process is particularly useful in scenarios such as data serialisation, web development, and secure data transfer.


Recommended Reading: Base64 Decoding with PowerShell

© 2024 ScriptWizards.net - Powered by Coffee & Magic