Showing posts with label Scripts Repositery. Show all posts
Showing posts with label Scripts Repositery. Show all posts

August 16, 2012

How to do a PAUSE

In the good old days, with cmd.exe batchs you can easily add a PAUSE in your script to allow you press a key to continue.

In Powershell you have to use the ReadKey() method. The only bug is that you can’t use ReadKey() if your not in the console. That could be a problem if you use PowerGUI or PowerShellISE to develop and run your scripts.

Here’s a little function that will do the trick :

#.SYNOPSIS 
# Emulation of PAUSE command (cmd)
#.DESCRIPTION
# Author : Jeffrey Snover [MSFT]
#.LINK
# http://blogs.msdn.com/b/powershell/archive/2007/02/25/pause.aspx
function Pause ([string]$Message="[Pause] Press Enter key to continue ...")
{
	if (((Get-Host).Name) -eq 'ConsoleHost') {
		Write-Host -NoNewLine $Message
		$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
		Write-Host ""
	}
	Else {
	Read-Host -Prompt $message
	}
}

Thanks to Jeffrey Snover for this code.

December 9, 2010

How to display a Yes/No message box ?

There isn’t a msgbox or an input function in Powershell, but you can directly call Windows.Forms.MessageBox  to do it. Thansks to Bart De Smet for his tutorial about that.

[reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") | out-null

#.SYNOPSIS 
# Display a confrimation dialog
# Return$True if the user click 'Yes'
#.LINK
# http://bartdesmet.net/blogs/bart/archive/2006/09/16/4429.aspx
function ConfirmMessageBox {
	param(
		[parameter(
		Mandatory=$False)]
		[String]$WinTitle='PowerShell Script',
		[parameter(
		Mandatory=$False)]		
		$MsgText='Do you really want to continue ?'
	)
	$result = [Windows.Forms.MessageBox]::Show($MsgText, $WinTitle, [Windows.Forms.MessageBoxButtons]::YesNo, [Windows.Forms.MessageBoxIcon]::Question)
	If ($result -eq [Windows.Forms.DialogResult]::Yes) {
		Return $true
	}
	Else {
		Return $false
	}
}

May 13, 2010

Get members of an active directory group including members of nested groups

Copy this script and save it as get-GroupNestedMembers.ps1

#
# .SYNOPSIS 
#   Get members of an active directory group including members
#   of nested groups
#	
# .DESCRIPTION
#   Search Active Dircetory to find a group and get members of
#   that group including members of nested groups. Return
#   an object.
#
#   Author   : Jean-Pierre.Paradis@fsa.ulaval.ca
#   Date     : May 13, mars 2010
#   Version  : 1.00
#   Language : PowerShell 2.0
#    
# .PARAMETER GroupName
#   Name of the group (mandatory)
#
# .PARAMETER OU
#   Distinguished name of an Organizational Unit (OU) to search (optional)
#
# .LINK
#   Inspired by http://gallery.technet.microsoft.com/ScriptCenter/en-us/1228cdfa-9c04-4bc7-a016-11b492c704d2
#   from Trevor Hayman
#
# .EXAMPLE
#   C:\PS> .\get-GroupNestedMembers.ps1 -groupname "mygroup"
# .EXAMPLE
#   C:\PS> .\get-GroupNestedMembers.ps1 -groupname "mygroup" -ou "OU=Experimentation,DC=mydomain,DC=com"
# .EXAMPLE
#   C:\PS> .\get-GroupNestedMembers.ps1 -groupname "mygroup" -verbose
# .EXAMPLE
#   C:\PS> .\get-GroupNestedMembers.ps1 -groupname "mygroup" | Out-GridView


#REQUIRES -version 2.0

param (
	[parameter(
	Mandatory=$true,
	ValueFromPipeline=$True)]
	[String]$GroupName,
	
	[parameter(
	Mandatory=$false)]
	[String]$OU=""

	) 

Set-StrictMode -Version 2.0

Function Add-GroupMembers {
# .SYNOPSIS 
#   Add member of -GroupDistinguishedName to $Script:ColGroupMembers
	param (
		[parameter(
		Mandatory=$true)]
		[String]$GroupDistinguishedName
		)
	 $objGroup = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$GroupDistinguishedName")
	 $MemberList = $objGroup.member
	 ForEach ($member in $MemberList) {
	 	$objMember = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$member")
		if ($objMember.objectCategory.Value.Contains("Group")) {
			Add-GroupMembers -GroupDistinguishedName $objMember.DistinguishedName
			}
		Else {
			$Script:ColGroupMembers.add((New-Object psobject -Property @{Name=[string]$objMember.name;DisplayName=[string]$objMember.DisplayName;DistinguishedName=[string]$objMember.DistinguishedName;ImmediateParent=[string]$objGroup.name}))
			}
	 	}
}

# Setup AD search root
if ($OU -ne "") {
	Write-Verbose "Searching from $OU"
	$root=[System.DirectoryServices.DirectoryEntry] "LDAP://$OU"
	}
Else {
	$root=[string]""
	}
$search = [ADSISearcher] $root

# Find the group
$search.Filter = "(&(objectCategory=Group)(cn=$GroupName))"
$result = $search.FindOne()
If ($result -eq $null) {
	Write-Error "Group '$groupname' not found !"
	exit
	}
Write-Verbose "Found group $($result.Properties.distinguishedname)"

# Create a collection to store de results
$psobjectStrongName = (New-Object psobject).psobject.GetType().AssemblyQualifiedName
$Script:ColGroupMembers = New-Object "System.Collections.ObjectModel.Collection``1[[$psobjectStrongName]]"

Add-GroupMembers -GroupDistinguishedName $result.Properties.distinguishedname
Write-verbose "Found $($ColGroupMembers.count) member(s)"
return ($ColGroupMembers|Sort-Object 'Name')

April 16, 2010

Create users in Active Directory from a CVS file

[update august 23th, 2010] This is a new version (1.10) that allows you put an ‘#’ in the ‘password’ field to be able to update properties of an existing user without modifying his password.

#
# .SYNOPSIS 
#   Create users in Active Directory from a CVS file (';' delimited).
#	
# .DESCRIPTION
#   The CSV file used to create the users must have a special format.
#   The first line of the CVS file must contain columns names.
#   Each column name must correspond exactly to an attribute name of 
#   a user object in the Active Directory.
#   All Active Directory attributes containing a text value can be used.
#  
#   The following columns (attributes) are mandatory :
#
#      Name               If this field contain a '#', the line will
#                         ingnored (commented).
#      OU
#      Password           If this filed contain # '#', the password
#                         will not be set. Of course the user must
#                         already exist.
#
#   The follwing attributes (columns) cannot be used, they are automatically
#   generated by the script :
#
#      sAMAccountName
#      userPrincipalName
#
#   The following special columns (attributes) are handle by the script :
#
#      OU                  Organizational Unit containing the user to be created.
#                          The distingushedName of the domain will be appended.
#      sAMAccountName      Automicically set to the value of the Name column
#      userPrincipalName   Automicically set to the value of the Name column
#                          plus the canonicl name of the domain
#                         (ex: user1@domain.com)
#      MemberOf            List of group names separeted by a comma (,) do not
#                          specified the full distingushedName or the group
#                          only the name, the script will do the rest.
#      AccountExpires      Set the expiration date of the new account
#
#   If an attribute of the new user cannot be set, the new user account will
#   be left disabled.
#
#   If the user account already exists, the script will not end and will
#   try to set the attributes of the accounts.
#
#   Here's a sample CSV file :
#   Name;OU;Password;displayName;mail;description;AccountExpires;memberOf
#   PdelphiC1;ou=UtilisateursExternes;!42mj428;My First Poweshell User;chico@hotmail.com ;This is a test;2010-09-15;group 1,group 2
#   PdelphiC2;ou=UtilisateursExternes;$93me934;My second PowerShell User;binou@hotmail.com ;This is a test;2010-09-15;group 3
#   # This is a sample input file for Import-Users.ps1
#
#   Author   : Jean-Pierre.Paradis@fsa.ulval.ca
#   Date     : august 23,  2010
#   Version  : 1.10
#   Language : PowerShell 2.0
#    
# .PARAMETER CSVInputFile
#   Input file name.
#		
# .EXAMPLE
#  C:\PS> .\Import-users.ps1 -CSVInputFile "users.cvs"
#
# .LINK 
#  Inspire by Don Jones and Jeffrey Hicks in 'Windows powershell 2.0 TFM' from Sapien Press
#

#REQUIRES -version 2.0

param (
	[parameter(
	Mandatory=$true)]
	[String[]]$CSVInputFile
	) 
	
Set-StrictMode -Version 2.0

# Script parameters
# $CSVInputFile="newusers.csv"
$Delimiter=";"
$DirectoryServicesCOMException_ENTRY_EXISTS=-2147019886

function get-scriptdirectory {

# .SYNOPSIS 
# 	Return the current script directory path, compatible with PrimalScript 2009
# 	Equivalent to VBscript fso.GetParentFolderName(WScript.ScriptFullName)
# 	Requires PowerShell 2.0
#    
# .DESCRIPTION
#	Author   : Jean-Pierre.Paradis@fsa.ulaval.ca
#	Date     : March 31, 2010
#	Version  : 1.01
#
# .LINK 
# 	http://blog.sapien.com/index.php/2009/09/02/powershell-hosting-and-myinvocation/

    if (Test-Path variable:\hostinvocation) 
    	{$FullPath=$hostinvocation.MyCommand.Path}
    Else {
   		$FullPath=(get-variable myinvocation -scope script).value.Mycommand.Definition }  	
	if (Test-Path $FullPath) {
    	return (Split-Path $FullPath) 
		}
    Else {
		$FullPath=(Get-Location).path
		Write-Warning ("Get-ScriptDirectory: Powershell Host <" + $Host.name + "> may not be compatible with this function, the current directory <" + $FullPath + "> will be used.")
		return $FullPath
		}
}

function get-GroupDN {
# .SYNOPSIS 
# 	Return an Active Directory group distinguished name
param (
	[parameter(
	Mandatory=$true)]
	[String[]]$GroupShortName
	)
	
	$AdSearch = [ADSISearcher] ""
	$AdSearch.Filter = "(&(objectCategory=group)(cn=$($GroupShortName)))"
	$AdResult = $ADSearch.FindOne()
	if ($AdResult -ne $null) {
		return $AdResult.properties.distinguishedname
		}
	Else {
		Write-Warning ("get-GroupDN: Can't find group named <$($GroupShortName)>")
		return $null
		}
}


function add-UserToGroups {
# .SYNOPSIS 
# 	Add a user to an array of groups
param (
	[parameter(
	Mandatory=$true)]
	[String]$UserDistinguishedName,

	[parameter(
	Mandatory=$True)]
	[System.Array]$Groups
	
	)
	
	Foreach ($GroupName in $Groups) {
		$GroupDN = get-GroupDN($GroupName)
		if ($GroupDN -ne $null) {
			Write-host "   Adding to group '$($groupname)' ..."
			$GroupObj=[adsi]("LDAP://"+$GroupDN)
			$GroupObj.member.add($UserDistinguishedName) >$null
			
			Try {
				$GroupObj.SetInfo()
				}
			Catch [System.DirectoryServices.DirectoryServicesCOMException] {
				If ($_.exception.ErrorCode -eq $DirectoryServicesCOMException_ENTRY_EXISTS) {
					Write-Warning "The user is already a member."
					}
				else {
					Throw $_
					}
				}
			}
	}
}


# Read the data file and filter any commented line
$CSVInputFileFullPath = (get-scriptdirectory($CSVInputFile)) + "\" + $CSVInputFile
$imported=Import-Csv $CSVInputFileFullPath -Delimiter $Delimiter | where {$_.name -notlike '#*'}

# retrieve list of csv column headings
# Each column heading should correspond to an ADSI user property name
$properties=$imported | Get-Member -type noteproperty | `
where {$_.name -ne "OU" -and $_.name -ne "Password" `
-and $_.name -ne "Name" -and $_.name -ne "sAMAccountName" `
-and $_.name -ne "userPrincipalName"}

# Get the domain canonicalName (mydomain.com) & distinguishedname
$rootDomain=[ADSI]""
$rootDomain.RefreshCache(@("canonicalName"))
$rootDomainCanonicalName=($rootDomain.get("canonicalName") -replace "/","")
$rootDomainDistinguishedName=$rootDomain.distinguishedName

# Loop throuth the data
foreach ($user in $imported) {
 
 		# Create the account
        $UserAlreadyExist=$false
		$OUDistinguishedName = $user.OU+","+$rootDomainDistinguishedName
		Write-Host "Creating User '$($user.Name)' in '$($OUDistinguishedName)' ..."
		[ADSI]$OU="LDAP://"+$OUDistinguishedName
		$newUser=$OU.Create("user","CN="+$user.Name)
		$newUser.Put("sAMAccountName",$user.Name)
		
		# Get the domain canonicalName (mydomain.com)
		$rootDomain=[ADSI]""
		$rootDomain.RefreshCache(@("canonicalName"))
		# Set userPrincipalName
		$newUserPrincipalName=$user.Name + "@" + $rootDomainCanonicalName
		$newUser.Put("userPrincipalName",$newUserPrincipalName)
		
		# commit creation to Active Directory
		Try {
			$newUser.SetInfo()
			}
		Catch [System.DirectoryServices.DirectoryServicesCOMException] {
			If ($_.exception.ErrorCode -eq $DirectoryServicesCOMException_ENTRY_EXISTS) {
				Write-Warning "The object already exist, will try to reset properties."
				$newUser=[adsi]("LDAP://"+"CN="+$user.Name+","+$OUDistinguishedName)
                $UserAlreadyExist=$true
				}
			else {
				Throw $_
				}
			}
			
		# set a password 
        
        If ($user.password -notlike '#*') {
		  Write-Host ("   Setting password")
		  $newUser.SetPassword($user.Password)
		  $newUser.SetInfo()
        }

		# set additional properties
		foreach ($prop in $properties) {
		$value=$user.($prop.name)
		if (($value -ne $Null) -and ($value.length -gt 0)) {
			Switch ($prop.name ) {
				"MemberOf" {
					# Write-Host ("   Adding to groups $($Value)")
					add-UserToGroups $newUser.distinguishedname @($value -split ",")
					}
				"AccountExpires" {
					$newAccountExpires = ($value -as [datetime])
					if ($newAccountExpires -ne $null) {
						Write-Host ("   Setting '$($prop.name)' to $($newAccountExpires)")
						$newUser.InvokeSet("AccountExpirationDate",$newAccountExpires)
						}
					Else {
						Write-Warning "   Can't convert '$($value)' to acceptable format for AccountExpires"
						}
					}
				default {
					#only set properties that have values
					Write-Host ("   Setting '$($prop.name)' to '$($value)'")
					$newUser.put($prop.name,$value)
					}
				}
			}
		}
		$newUser.SetInfo()
		
		# Activate the account
        If ($UserAlreadyExist -ne $True) {
          Write-Host ("   Enabling account")
		  $newUser.Invokeset("AccountDisabled", "False")
		  $newUser.SetInfo()
        }
 }

April 7, 2010

How to get the script’s directory ?

Sometimes you want to know what directory you script is in, here’s a function that return that value :

function get-scriptdirectory {

# .SYNOPSIS 
# 	Return the current script directory path, compatible with PrimalScript 2009
# 	Equivalent to VBscript fso.GetParentFolderName(WScript.ScriptFullName)
# 	Requires PowerShell 2.0
#    
# .DESCRIPTION
#	Author   : Jean-Pierre.Paradis@fsa.ulaval.ca
#	Date     : March 31, 2010
#	Version  : 1.01
#
# .LINK 
# 	http://blog.sapien.com/index.php/2009/09/02/powershell-hosting-and-myinvocation/

    if (Test-Path variable:\hostinvocation) 
    	{$FullPath=$hostinvocation.MyCommand.Path}
    Else {
   		$FullPath=(get-variable myinvocation -scope script).value.Mycommand.Definition }  	
	if (Test-Path $FullPath) {
    	return (Split-Path $FullPath) 
		}
    Else {
		$FullPath=(Get-Location).path
		Write-Warning ("Get-ScriptDirectory: Powershell Host <" + $Host.name + "> may not be compatible with this function, the current directory <" + $FullPath + "> will be used.")
		return $FullPath
		}
}