Category : PowerShell

PowerShell Windows

Safely change the Administrator Password

In one of my current projects, the customer wants to change the password of the Active Directory built-in Administrator account. This account was used several years for setting up tasks, running services and all kinds of things. To ensure that all major business applications will not be affected by that change, we needed to identify all processes and persons using the Administrator account and create separate service accounts for these applications.

Read More
PowerShell Programming Windows

Change DNS settings on multiple Windows Servers and Workstations

During several Active Directory migration projects I needed to change the DNS server IP addresses on several computers if the DNS service was installed on the Active Directory Domain Controller. Therefore I wrote a little PowerShell script to connect to remote computer and change the DNS server IP address in the network connection via WMI to the onces specified in the script.

This makes changing the IP address of a DNS server much easier because all Windows systems based on Windows Server 2008 / Vista or newer can be edited by using this PowerShell script.

Read More
Bechtle-Blog PowerShell Windows

Using Windows certificate store in Mozilla Firefox

Lots of companies are using Mozilla Firefox in their corporate environment. Firefox came up with a great new feature in the latest version – it will support Windows enterprise trusted root certificates! No more need for adding certificates to Firefox seperatly using the keytool:

firefox-connection-not-secure

Just use the Windows Active Directory Group Policies to deploy your certificates – most of you already do this for use with Microsoft Internet Explorer and other software. To enable this great new feature Firefox introduced a new configuration parameter named security.enterprise_roots.enabled this needs to be set to true in the about:config page:

Read More
Bechtle-Blog Office 365 PowerShell

Assign Office 365 licenses based on Active Directory groups

I’ve done several Microsoft Office 365 project with together with some of our customers. In most implementations I was asked if there’s a way to assign Office 365 licenses (a.k.a. plans) to users based on their Active Directory group memberships.

Most companies have built their entire permission model on Microsoft Active Directory. With Active Directory Federation Services (ADFS) Microsoft offers a powerful and great tool for synchronizing user and group account from the customers on-premise environment into the Office 365 cloud.

Unfortunately there is no built-in technique to automatically assign licenses. Therefore I wrote a small PowerShell script to complete this task.

Read More
PowerShell Programming

Update environment variables in current process

Currently, I’m involved in a huge PowerShell based deployment project for one of our major customers. The whole deployment process including several WPF-based GUIs are written in PowerShell. This week we had a new issue to fix regarding environment variables. First of all some background knowledge about environment variables in Windows.

Environment Variables are stored inside the registry and each process will read them from the registry and store the variables in its own environment. Each new process (called sub-process) that will be started from another process will inherit the environment variables from its parent process.
The problem will be if the parent process starts several sub-processes and each of them will subsequently change / expand environment variables like the %PATH% variable. Sub-Process #2 is not aware of the changes Sub-Process #1 made to the environment variables.

To work around this issue, I wrote a small PowerShell function which utilizes .NET Framework Methods to re-read the environment variables and store them for the current process:

#####################################################################
##
## (C) 2015 Michael Miklis (michaelmiklis.de)
##
##
## Filename:      Update-Environment.ps1
##
## Version:       1.0
##
## Release:       Final
##
## Requirements:  -none-
##
## Description:   Refresh the current environment variables
##
## This script is provided 'AS-IS'.  The author does not provide
## any guarantee or warranty, stated or implied.  Use at your own
## risk. You are free to reproduce, copy & modify the code, but
## please give the author credit.
##
####################################################################
Set-PSDebug -Strict
set-strictMode -version latest

function Update-Environment {
    <#
    .SYNOPSIS
    Refresh all environment variables

    .DESCRIPTION
    Reads all environement variables from registry for scope user and machine
    and updates the current process environment variables
        
    .EXAMPLE
    Update-Environment
    #>


    # first update the environment variables from the machine scope
    $ENV_MACHINE = ([Environment]::GetEnvironmentVariables('Machine'))
    foreach ($EnvVar in $ENV_MACHINE.keys) {
        Set-Item "Env:$($EnvVar)" -Value $ENV_MACHINE[$EnvVar]
    }

    # second update the environment variables from the user scope
    $ENV_USER = ([Environment]::GetEnvironmentVariables('User'))
    foreach ($EnvVar in $ENV_USER.keys) {
        Set-Item "Env:$($EnvVar)" -Value $ENV_USER[$EnvVar]
    }

    # now Update the Path variable (path variable gets
    # combined by User:Path and Machine:Path
    # User:Path has precedence over Machine:Path
    if ($ENV_USER.ContainsKey('Path')) {
        Set-Item env:Path -Value ((($ENV_USER.Path -split ";") + ($ENV_MACHINE.Path -split ";") | select -Unique) -join ";")
    }

}

#_____________________________________________________________________________________________

#call Update-Environment() function
Update-Environment

We’ve added the function to our framework – this will be the first function that we’re calling after every external process (Start-Process), we’ve started.

Read More
PowerShell

Set Creation- and Modification-Date from Filename

After my return of my last vacation, I had a bunch of videos that I wanted to edit, transcode and archive. First I renamed the files based on their creation date so that this information is being preserved and consistent during the whole process.
When my editing and transcoding was done I just needed to set the file’s modification and creation date back to when it was originally taken. To do this job I created a small PowerShell Script I want to share with you:

$Directory = "C:PathtoFiles"
$DateFormat = "yyyy-MM-dd_HHmmss"


foreach ($file in (Get-ChildItem $Directory)) {
    $date_from_file=[datetime]::ParseExact($file.Name.Substring(0,$file.Name.Length-4), $DateFormat, $null)

    $file.CreationTime = $date_from_file
    $file.LastAccessTime = $date_from_file
    $file.LastWriteTime = $date_from_file

    Write-Host ($file.Name + " - " + $date_from_file)
}

Here’s the result – the date / timestamp in the filename is identical with the actual file date:

Set Creation- and Modification-Date from Filename

Read More
PowerShell Windows

Creating PowerShell scripts with a GUI

I’ve created several PowerShell scripts that utilize Windows Presentation Foundation (WPF) for displaying a graphical user interface (GUI). The ability to use WPF GUIs enables you to combine PowerShell scripting and professional-looking GUIs – not like the old-school HTA GUIs in VBScripts.

WPF-Application

WPF is completely being build on XML / XAML files – and these files can be build using the graphical forms designer in Visual Studio Community Edition

Read More
PowerShell

Script-Gallery: Fix-Printer.ps1

#######################################################################
## (C) 2015 Michael Miklis (michaelmiklis.de)
##
##
## Filename:      Fix-Printer.ps1
##
## Version:       1.0
##
## Release:       Final
##
## Requirements:  -none-
##
## Description:   Script for fixing fqdn during computer domain
##                movement.
##
## This script is provided 'AS-IS'.  The author does not provide
## any guarantee or warranty, stated or implied.  Use at your own
## risk. You are free to reproduce, copy & modify the code, but
## please give the author credit.
##
####################################################################
Set-PSDebug -Strict
Set-StrictMode -Version latest


function Fix-Printer {
    <#
    .SYNOPSIS
    Fixes printer fqdn references in registry 

    .DESCRIPTION
    The Fix-Printer CMDlet fixes the serverName, uNCName and url registry key
    for the windows spooler service

    .PARAMETER OldDomain
    FQDN of the old domain

    .PARAMETER NewDomain
    FQDN of the new domain

    .EXAMPLE
    Fix-Printer -OldDomain "olddomain.com" -NewDomain "newdomain.com"

    .NOTES
    You need to run this CMDlet with elevated permissions
    #>
    
    param (
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]$OldDomain,
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]$NewDomain
    )

    foreach ($printer in (Get-ChildItem -Path HKLM:SYSTEMCurrentControlSetControlPrintPrinters)) {
    
        if ((Test-RegistryValue -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler") -Value ("serverName")) -eq $true) {
            $strOldVal = (Get-ItemProperty -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler")).serverName
            Set-ItemProperty -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler") -Name "serverName" -Value $strOldVal.Replace($olddomain, $newdomain)
        }
        
        if ((Test-RegistryValue -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler") -Value ("uNCName")) -eq $true) {
            $strOldVal = (Get-ItemProperty -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler")).uNCName
            Set-ItemProperty -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler") -Name "uNCName" -Value $strOldVal.Replace($olddomain, $newdomain)
        }
        
        if ((Test-RegistryValue -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler") -Value ("url")) -eq $true) {
            $strOldVal = (Get-ItemProperty -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler")).url
            Set-ItemProperty -Path ("HKLM:SYSTEMCurrentControlSetControlPrintPrinters" + $printer.PSChildName + "DsSpooler") -Name "url" -Value $strOldVal.Replace($olddomain, $newdomain)
        }
    }
}

#___________________________________________________________________

function Test-RegistryValue {
    <#
    .SYNOPSIS
    Tests existence of regisry value (C) by Jonathan Medd

    .DESCRIPTION
    The Test-RegistryValue CMDlet was created by Jonathan Medd

    .PARAMETER Path
    Registry path

    .PARAMETER Value
    Registry value

    .EXAMPLE
    Test-RegistryValue -Path "HKCU:Environment" -Value "TEMP"
    #>
    
    param (
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]$Path,
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]$Value
    )

    try {
        Get-ItemProperty -Path $Path | Select-Object -ExpandProperty $Value -ErrorAction Stop | Out-Null
        return $true
    }

    catch {
        return $false
    }
}

Fix-Printer -OldDomain "olddomain.com" -NewDomain "newdomain.com"

Read More
PowerShell Windows

Disable IPv6 in Windows for a specific network connection only

Sometimes you want to disable IPv6 only on a specified network interface, instead of disabling IPv6 completely:

IPv6_Bind

Microsoft has released a KB article how to disable the individual IPv6 components in Windows – but not for an individual interface:
https://support.microsoft.com/en-us/kb/929852

I wrote a small PowerShell script that unbinds the IPv6 protocol. The PowerShell script is modifying the bindings in the registry – therefore a reboot is needed for this setting to take effect:

$UnbindID = $(Get-WmiObject -Class 'Win32_NetworkAdapter' | Where-Object {$_.NetConnectionID -eq 'Ethernet'}).GUID
$LinkageKey = $(Get-ItemProperty -Path 'HKLM:SYSTEMCurrentControlSetservicesTcpip6Linkage').Bind | Select-String -Pattern $UnbindID -NotMatch -SimpleMatch
Set-ItemProperty -Path 'HKLM:SYSTEMCurrentControlSetservicesTcpip6Linkage' -Name 'Bind' -Type MultiString -Value $LinkageKey

Note: According to your environment and operating system version and language, you may need to change the network connection name (‘Ethernet’ in my example’) to fit your interface / connection name.

Read More
PowerShell Windows

PowerShell Best Practices: Set-StrictMode

During some research for PowerShell best practices I came across the following blog post on the Hey Scripting Guy Blog from Microsoft:
http://blogs.technet.com/b/heyscriptingguy/archive/2014/12/03/enforce-better-script-practices-by-using-set-strictmode.aspx

By using the Set-StrictMode cmdlet, we can enforce some common “best practice” coding techniques that you can use with your scripts. In yesterday’s post, I used the –Strict parameter with Set-PSDebug. This enforces the variable declaration in a script. But with Set-StrictMode, we get that plus a little more. The scope is limited to the current scope and child scopes. By default, Set-StrictMode is turned off to prevent error messages while you are writing the script.

From now on, all my PowerShell scripts will start with “Set-StrictMode -Version latest” and “Set-PSDebug -Strict”:

Set-PSDebug -Strict
Set-StrictMode -Version latest
Read More
1 2