PowerShell - Mes fonctions préférées

Dans cette article, je vous propose de partager avec vous, des fonctions que j'utilise quotidiennement dans mes scripts PowerShell.

Définir le racine du script dans toutes circonstances

Ce n'est pas vraiment une réelle fonctions car si on l'écrivait comme telle, il n'apporterait rien de plus que si l'on mettait au début de votre script.

#=============== Variable for use Root folder of PS1 ====================
If ($psISE)
{
    $currentScriptDirectory = Split-Path -Parent -Path $psISE.CurrentFile.FullPath
}
If (!$currentScriptDirectory)
{
    If ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
    {
        $currentScriptDirectory = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
    }
    Else
    {
        $currentScriptDirectory = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0])
    }
}
#========================================================================
Maintenant, dans votre script quand vous utiliserez la variable $currentScriptDirectory vous aurez le chemin racine de votre script, qu'il soit executé dans PowerShell ISE, PowerShell Core, PowerShell Version 1 ou 2.
Si vous souhaitez générer des variables qui permettent d'utiliser un dossier qui se trouve dans l'aborescence de votre script, vous pouvez faire comme ceci:

$DLLLibrary = Join-Path -Path $currentScriptDirectory -ChildPath 'DLL\'
#or
$DLLLibrary = $currentScriptDirectory + '\DLL\'
J'espère qu'il pourra bien vous aider comme il m'accompagne dans tous mes scripts.

Le cas PS2EXE

Il existe une exception à cette déclaration de chemin racine, cela sera uniquement lorsque vous utiliserez PS2EXE de Ingo Karstein, car comme il fait de l'interprétation ligne à ligne, il faudra passer par une récupération des processus en cours pour pouvoir déterminer le chemin racine, comme ceci :

 $FullPathToEXE = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
 $currentScriptDirectory = [System.IO.Path]::GetDirectoryName($FullPathToEXE)
 #le chemin racine sera la variable $currentScriptDirectory

Write-ColorOutput

Et si on mettait de la couleur dans Write-Output, il est possible que l'on a déjà entendu que Write-Host est une fonction pratique mais que cette fonction soit critiquée, je vous invite à lire cette article du blog de Jeffrey Snover pour comprendre un peu plus.

Cependant, il est très probable que vous vous disiez: Mais attends, si je n'utilise pas Write-Host. Mais alors comment je peux mettre de la couleur ?

Et j'ai trouvé ceci : 
function Write-ColorOutput
{
    [CmdletBinding()]
    Param(
         [Parameter(Mandatory=$False,Position=1,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][Object] $Message,
         [Parameter(Mandatory=$False,Position=2,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][ConsoleColor] $ForegroundColor,
         [Parameter(Mandatory=$False,Position=3,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)][ConsoleColor] $BackgroundColor,
         [Switch]$NoNewline
    )    

    # Save previous colors
    $previousForegroundColor = $host.UI.RawUI.ForegroundColor
    $previousBackgroundColor = $host.UI.RawUI.BackgroundColor

    # Set BackgroundColor if available
    if($BackgroundColor -ne $null)
    { 
       $host.UI.RawUI.BackgroundColor = $BackgroundColor
    }

    # Set $ForegroundColor if available
    if($ForegroundColor -ne $null)
    {
        $host.UI.RawUI.ForegroundColor = $ForegroundColor
    }

    # Always write (if we want just a NewLine)
    if($Message -eq $null)
    {
        $Message = ""
    }

    if($NoNewline)
    {
        [Console]::Write($Message)
    }
    else
    {
        Write-Output $message
    }

    # Restore previous colors
    $host.UI.RawUI.ForegroundColor = $previousForegroundColor
    $host.UI.RawUI.BackgroundColor = $previousBackgroundColor
}
Résultat:

C'est ultra gadget mais PSScriptAnalyzer sera très content.

Fonction Get-ComputerDistinguishedName

Pour cette fonction, j'avais besoin de récupérer l'information DistinguishedName d'un poste, avec la contrainte qu'il ne fallait pas utiliser les modules Active Directory qui ne sont pas toujours présent sur les postes (Source).

function Get-ComputerDistinguishedName
{
     param (
        [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Enter the computer name as Distinguishedname.")]
        $ComputerName=$(Read-Host -prompt "Enter the ComputerName")
    )
$filter = "(&(objectCategory=computer)(objectClass=computer)(cn=$ComputerName))"
$distinguishedname = ([adsisearcher]$filter).FindOne().Properties.distinguishedname
if ($null -eq $distinguishedname)
    {
        Write-Warning "Distinguishedname not found"
        return $false
    }
    else
    {
        return $distinguishedname
    }
}
Alternativement, pour les utilisateurs, j'ai fait ceci mais ce n'est pas trop intéressant.

function Get-UserDistinguishedName
{
     param (
        [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Enter the user name as Distinguishedname.")]
        $UserName=$(Read-Host -prompt "Enter the UserName")
    )
$filter = "(&(objectClass=user)(sAMAccountName=$UserName))"
$distinguishedname = ([adsisearcher]$filter).FindOne().Properties.distinguishedname
if ($null -eq $distinguishedname)
    {
        Write-Warning "Distinguishedname not found"
        return $false
    }
    else
    {
        return $distinguishedname
    }
}


Une version avancée de la fonction précédente


function Get-UserInformationWithADSI
{
     param (
        [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Enter the sAMAccountName.")]
        $UserName=$(Read-Host -prompt "Enter the UserName")
    )

$ACCOUNTDISABLE       = 0x000002
$DONT_EXPIRE_PASSWORD = 0x010000
$PASSWORD_EXPIRED     = 0x800000

$filter = "(&(objectClass=user)(objectCategory=person)(sAMAccountName=$UserName))"
([adsisearcher]$filter).FindOne() | ForEach-Object {

  $user = [adsi]$_.Properties.adspath[0]
  $Return = New-Object -Type PSCustomObject -Property @{
    SamAccountName       = $user.sAMAccountName[0]
    Name                 = $user.name[0]
    Mail                 = $user.mail[0]
    PasswordLastSet      = [DateTime]::FromFileTime($_.Properties.pwdlastset[0])
    Enabled              = -not [bool]($user.userAccountControl[0] -band
                           $ACCOUNTDISABLE)
    PasswordNeverExpires = [bool]($user.userAccountControl[0] -band
                           $DONT_EXPIRE_PASSWORD)
    PasswordExpired      = [bool]($user.userAccountControl[0] -band
                           $PASSWORD_EXPIRED)
  }

}

return $Return

}

Commentaires

Posts les plus consultés de ce blog

MRemoteNG - Voir les mots de passe dans l'application

PowerShell - Fonction - Exporter ces variables

PowerShell - Utiliser NSIS (Nullsoft Scriptable Install System) pour simplifier l'usage des scripts PS1