PowerShell Script to find all AD users who have the “cannot change password” box checked in a specific OU

# script to find all AD users who have the “cannot change password” box checked in a specific OU

# Windows Server 2016

# Powershell

Get-ADUser -Filter * -Properties CannotChangePassword -SearchBase “OU=specificOU,DC=TEST,DC=com” | where { $_.CannotChangePassword -eq “true” } | Format-Table Name, DistinguishedName


Create an ISO file with PowerShell post by Ben Liebowitz

Recently I came across this post. As a VMware admin, you often want to create an ISO as a quick method to copy files or installation files to a VM.

Ben Liebowitz shows how to create an ISO of large files with PowerShell. For the full post use the link below


All credit to  for this script

This is a copy of function to use incase the link above fails :

function itself:


#Get-Help About-Classesfunction New-IsoFile
<# .Synopsis Creates a new .iso file .Description The New-IsoFile cmdlet creates a new .iso file containing content from chosen folders .Example New-IsoFile “c:\tools”,”c:Downloads\utils” This command creates a .iso file in $env:temp folder (default location) that contains c:\tools and c:\downloads\utils folders. The folders themselves are included at the root of the .iso image. .Example New-IsoFile -FromClipboard -Verbose Before running this command, select and copy (Ctrl-C) files/folders in Explorer first. .Example dir c:\WinPE | New-IsoFile -Path c:\temp\WinPE.iso -BootFile “${env:ProgramFiles(x86)}\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\efisys.bin” -Media DVDPLUSR -Title “WinPE” This command creates a bootable .iso file containing the content from c:\WinPE folder, but the folder itself isn’t included. Boot file etfsboot.com can be found in Windows ADK. Refer to IMAPI_MEDIA_PHYSICAL_TYPE enumeration for possible media types: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366217(v=vs.85).aspx .Notes NAME: New-IsoFile AUTHOR: Chris Wu LASTEDIT: 03/23/2016 14:46:50 #>

[parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true, ParameterSetName=’Source’)]$Source,
[parameter(Position=2)][string]$Path = “$env:temp\$((Get-Date).ToString(‘yyyyMMdd-HHmmss.ffff’)).iso”,
[ValidateScript({Test-Path -LiteralPath $_ -PathType Leaf})][string]$BootFile = $null,
[string]$Title = (Get-Date).ToString(“yyyyMMdd-HHmmss.ffff”),

Begin {
($cp = new-object System.CodeDom.Compiler.CompilerParameters).CompilerOptions = ‘/unsafe’
if (!(‘ISOFile’ -as [type])) {
Add-Type -CompilerParameters $cp -TypeDefinition @’
public class ISOFile
public unsafe static void Create(string Path, object Stream, int BlockSize, int TotalBlocks)
int bytes = 0;
byte[] buf = new byte[BlockSize];
var ptr = (System.IntPtr)(&bytes);
var o = System.IO.File.OpenWrite(Path);
var i = Stream as System.Runtime.InteropServices.ComTypes.IStream;

if (o != null) {
while (TotalBlocks– > 0) {
i.Read(buf, BlockSize, ptr); o.Write(buf, 0, bytes);
o.Flush(); o.Close();

if ($BootFile) {
if(‘BDR’,’BDRE’ -contains $Media) { Write-Warning “Bootable image doesn’t seem to work with media type $Media” }
($Stream = New-Object -ComObject ADODB.Stream -Property @{Type=1}).Open() # adFileTypeBinary
$Stream.LoadFromFile((Get-Item -LiteralPath $BootFile).Fullname)
($Boot = New-Object -ComObject IMAPI2FS.BootOptions).AssignBootImage($Stream)


Write-Verbose -Message “Selected media type is $Media with value $($MediaType.IndexOf($Media))”
($Image = New-Object -com IMAPI2FS.MsftFileSystemImage -Property @{VolumeName=$Title}).ChooseImageDefaultsForMediaType($MediaType.IndexOf($Media))

if (!($Target = New-Item -Path $Path -ItemType File -Force:$Force -ErrorAction SilentlyContinue)) { Write-Error -Message “Cannot create file $Path. Use -Force parameter to overwrite if the target file already exists.”; break }

Process {
if($FromClipboard) {
if($PSVersionTable.PSVersion.Major -lt 5) { Write-Error -Message ‘The -FromClipboard parameter is only supported on PowerShell v5 or higher’; break }
$Source = Get-Clipboard -Format FileDropList

foreach($item in $Source) {
if($item -isnot [System.IO.FileInfo] -and $item -isnot [System.IO.DirectoryInfo]) {
$item = Get-Item -LiteralPath $item

if($item) {
Write-Verbose -Message “Adding item to the target image: $($item.FullName)”
try { $Image.Root.AddTree($item.FullName, $true) } catch { Write-Error -Message ($_.Exception.Message.Trim() + ‘ Try a different media type.’) }

End {
if ($Boot) { $Image.BootImageOptions=$Boot }
$Result = $Image.CreateResultImage()
Write-Verbose -Message “Target image ($($Target.FullName)) has been created”

Ben goes on to share how he was able to create a variable for the source data, and use get-childitem to get that location and pipe that to creating the ISO. See below:

$source_dir = “Z:\Install\App123”
get-childitem “$source_dir” | New-ISOFile -path e:\iso\app123.iso


List Computer Object in an Active Directory OU using PowerShell

How to get a list of computer objects in an active directory OU ( tested against Windows 2016 Active Directory )

A quick PowerShell script using Get-ADComputer  command, a wild card filter and a search base pointing to a specific OU


First import modules for active directory in powershell


Copy and edit the script below:

## cmd

## dsquery computer -name servername (server name in the OU to get the OU path)

#Example lists domain controller in test.com

#Export list of names to CSV

Get-ADComputer -Filter * -SearchBase “OU=Domain Controllers,DC=test,DC=com” | Select Name | export-csv C:\temp\DCs.csv


( Like the post click and advert of interest to give us support)

Sysinternals – Permissions, LoggedOn, Endpoints

How to Get the permission on folders:
Get-ChildItem | Get-ACL
Path | Owner | Access

or more in depth use:

GUI based : Run AccessEnum against the drive or folder – (SysInternals tool) and save to text file (Run as administrator or a specific user)

Who is logged on via the resource shares:
Launch cmd and run PSLoggedon (SysInternals tool)
Displays :
1) Users logged on locally
2) Users logged on via resource shares

List TCP and UDP Endpoints connected
Run TCPView application (SysInternals tool) and save to text file

Ever need to identify the before and after changes in Active Directory
Use : ADExplorer (SystInternals tool)

Download Sysinternals 

Suggested top 10 sysinternals tools
See an advert of interest, CLICK IT!  This site is funded by AD clicks.

Get-AdUser -Filter {Multiple Filters Complex } -Properties | Export to CSV

#Import AD modules

import-module servermanager
Add-WindowsFeature -Name “RSAT-AD-PowerShell” -IncludeAllSubFeature

#List AD user accounts and show DisplayName, Email, Title and export to CSV

Get-ADUser -Filter * -Properties DisplayName, EmailAddress, Title | select DisplayName, EmailAddress, Title | Export-CSV “C:\temp\Email_Addresses.csv”

#List AD user accounts and show DisplayName, Email, Title and export to CSV. Advanced filter to show ENABLED accounts only

Get-ADUser -Filter {Enabled -eq $true} -Properties DisplayName, SamAccountName, EmailAddress, Enabled, DistinguishedName | select DisplayName, SamAccountName, EmailAddress, Enabled, DistinguishedName | Export-CSV “C:\temp\Email_Addresses_allusers.csv”

#List AD user accounts and show DisplayName, Email, Title and export to CSV. Advanced filter to show ENABLED accounts only and email address ending @test.com

Get-ADUser -Filter {(Enabled -eq $true) -And (EmailAddress -Like “*@test.com”)} -Properties DisplayName, SamAccountName, EmailAddress, Enabled, DistinguishedName | select DisplayName, SamAccountName, EmailAddress, Enabled, DistinguishedName | Export-CSV “C:\temp\Email_Addresses_testdomain.csv”

Get a list of active computers which have logged on to the domain in the last 7 days

# Trying to work out is servers, laptops or desktops have been decommissioned

# Try this script

# Get a list of active computers which have logged on to the domain in the last 7 days

$Date = (Get-Date).AddDays(-7)

Get-ADComputer -Filter {LastLogonDate -gt $Date} | Select distinguishedName


# https://social.technet.microsoft.com/Forums/windows/en-US/4d412730-5937-48c2-bf17-0dc9db013241/list-active-computers-in-ad?forum=winserverDS

# Credit to Richard Mueller – MVP Enterprise Mobility (Directory Services)


Azure and Containers

What is a container?
A container is a live and running copy of an image which may have been customised.
An image is a read only copy of an image before it was running as a container

How do you implement containers in Azure

Two options, containers we deploy ourselves and containers Microsoft manage
Container can be running on Windows 2016 or Linux OS
CPU and Ram assigned to each individual container

Containers Limited security risk?
Microsoft offers Hyper-V running containers for those concerned
Azure container covers this way.
Others offer shared application containers.

Notes around Docker?
A docker file is like a script to build the container which takes a source and makes an app on an image, which makes a container as its running.

Docker has other tools: Docker toolbox, Docker client and Kitematic (GUI client)

How to Install Docker for Windows


Quick install guide :
1) Navigate to https://docs.docker.com/docker-for-windows/install/#download-docker-for-windows
On the Install Docker for Windows page, click Get Docker for Windows (Stable).
3) When prompted whether to run or save Docker for Windows Installer.exe, click Run.
4) Once the installation completed, click Close and log out.

When you make a mistake deploying a docker-machine .. Ie.. Forget to enter a region… But the machine builds and you enter an error state.
Start again by removing the docker-machine

Launch CMD as admin : docker-machine rm “machine name”


Kubernetes a management tools to for Docker. An alternative Docker Swarm for large scale
Deploy Kubernetes cluster for Linux containers

From <https://docs.microsoft.com/en-us/azure/container-service/kubernetes/container-service-kubernetes-walkthrough>


DCOS getting started with Kubernetes


Set Up Your Microsoft Azure Environment With PowerShell

Step 1 : Install Command Line Tool For PowerShell


Step 2: Launch PowerShell as Administrator

Type in the following

# get the Azure RM module installed first

Install-Module AzureRM

# import the module for use

Import-Module AzureRM


Step 3: Getting started with IaaS & PowerShell scripts

#Create a resource group

New-AzureRmResourceGroup -Name Project1ResourceGroup -Location “West Europe”

#Create a new subnet and store in a variable

$Project1Subnet1 = New-AzureRmVirtualNetworkSubnetConfig -Name Project1Subnet1 -AddressPrefix “”

#Create new network and add the subnet stored in variable

$virtualNetwork = New-AzureRmVirtualNetwork -Name ProjectNetwork -ResourceGroupName Project1ResourceGroup -Location “West Europe” -AddressPrefix “” -Subnet $Project1Subnet1

#add additional subnet to the network

Add-AzureRmVirtualNetworkSubnetConfig -Name Project2Subnet2 -VirtualNetwork $virtualNetwork -AddressPrefix “”

$virtualNetwork | Set-AzureRmVirtualNetwork



Sign up to GitHub.. Create your own repository https://github.com/

Git Hub Desktop to grab a bunch of files… Full Git hub desktop to sync https://desktop.github.com/

Add VM Custom Annotation and Create a Report on Annotations

Add Custom Attributes for Notes Annotation

A request to add custom attributes for Virtual Machines when using the fat client. (Web client in 5.1 and 5.5 requires a plugin, see “vsphere-web-client-plugin-for-custom”) 6.0 doesn’t see the attributes in the Web Client, 6.5 does, see the 6.5 KB.

Fields required : Applications, Company Name, Owner, Role, VM Cost

Code Below

Connect-VIServer VC6.test.domain
New-CustomAttribute -Name “Company Name” -TargetType VirtualMachine
New-CustomAttribute -Name “VM Cost” -TargetType VirtualMachine
New-CustomAttribute -Name “Role” -TargetType VirtualMachine
New-CustomAttribute -Name “Owner” -TargetType VirtualMachine
New-CustomAttribute -Name “Applications” -TargetType VirtualMachine
disconnect-VIServer VC6.test.domain -Confirm:$false


Add the details required


Bulk Virtual Machines Deployment and Zero Clicks Part 1

Add additional code code to add annotation in to the bulk script

$companyname = $item.companyname
$applications = $item.applications
$owner = $item.owner
$role = $item.role
$cost = $item.cost

#Get the Specification and set the Nic Mapping
New-OSCustomizationNicMapping -Spec $custspec -IpMode UseStaticIp –Position 1 -IpAddress $ipaddr -SubnetMask $subnet -DefaultGateway $gateway -Dns $pdns,$sdns

#Create VM using Template with the adjusted Customization Specification
New-VM -Name $vmname -Template $template -Datastore $datastore -VMHost $vmhost -ResourcePool $resourcepool | Set-VM -OSCustomizationSpec $custspec -Confirm:$false

#Set the Network Name
Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $vlan -Confirm:$false

#Set the CPU and Memory
Get-VM -Name $vmname | Set-VM -MemoryGB $ram -NumCPU $cpu -Confirm:$false

#Set some custom attribute fieds
#New-CustomAttribute -Name “VM Cost” -TargetType VirtualMachine
#New-CustomAttribute -Name “Role” -TargetType VirtualMachine
#New-CustomAttribute -Name “Owner” -TargetType VirtualMachine
#New-CustomAttribute -Name “Applications” -TargetType VirtualMachine

#Set annotation value for custom attributes
Set-Annotation -Entity $vmname -CustomAttribute “CompanyName” -Value “$companyname”
Set-Annotation -Entity $vmname -CustomAttribute “Applications” -Value “$applications”
Set-Annotation -Entity $vmname -CustomAttribute “Owner” -Value “$owner”
Set-Annotation -Entity $vmname -CustomAttribute “Role” -Value “$role”
Set-Annotation -Entity $vmname -CustomAttribute “VM Cost” -Value “$cost”



RV Tools can be used to produce an MS Excel file to output a list of virtual machines and custom annotations RV Tools download


Alternative Report function used

Function Code Below
(greg-get-annotations tested successfully in our lab)……………….

function greg-get-annotations {
<# .DESCRIPTION Greg-get-annotations function stores information about annotation fields for vms in given cluster or in all clusters in VC. It stores the result in an arraylist $vms, you can either create a csv report from this object or display it on screen greg-get-annotations |export-csv -NoTypeInformation c:\file1.csv will export it to csv file etc… greg-get-annotations |format-table VMname,Cluster,CreatedOn,Notes will just display on screen a table with annotations that include : vm name, its cluster and field “CreatedOn” and Notes   .PARAMETER clustername Specifies the clustername against wchi report will be built   .EXAMPLE greg-get-annotations -clustername ‘cluster01’|Export-Csv c:\annotation-report.csv Will procude report on vms that resides in ‘cluster01’ and store it in csv file   .EXAMPLE greg-get-annotations -clustername ‘cluster01’|ft * Will procude report on vms that resides in ‘cluster01’ output it to screen   .EXAMPLE greg-get-annotations |Export-Csv c:\annotation-report.csv Will procude report on vms that resides in all clusters and output it to screen   .EXAMPLE greg-get-annotations Without specified -clustername switch, it will do report regarding all clusters in VC   .NOTES AUTHOR: Grzegorz Kulikowski LASTEDIT: 05/30/2011     #>
param ([string]$clustername)
if(!($clustername)){$clusters=Get-Cluster}else{$clusters=Get-Cluster $clustername}
$VMs=New-Object Collections.ArrayList
foreach ($cluster in $clusters)  {
foreach ($vmview in (get-view -ViewType VirtualMachine -SearchRoot $cluster.id)) {
$vm=New-Object PsObject
Add-Member -InputObject $vm -MemberType NoteProperty -Name VMname -Value $vmview.Name
Add-Member -InputObject $vm -MemberType NoteProperty -Name Notes -Value $vmview.Config.Annotation
Add-Member -InputObject $vm -MemberType NoteProperty -Name Cluster -Value $cluster.Name
foreach ($CustomAttribute in $vmview.AvailableField){
Add-Member -InputObject $vm -MemberType NoteProperty -Name $CustomAttribute.Name -Value ($vmview.Summary.CustomValue | ? {$_.Key -eq $CustomAttribute.Key}).value
return $VMs

greg-get-annotations |Export-Csv c:\annotation-report.csv


CSV Out Put