PI Services

Le blog des collaborateurs de PI Services

Script - Crowdstrike - Exemple d'utilisation du module PSFalcon

Falcon Crowdsrike est l'un des antivirus next generation (EDR) les plus en vue et les plus performants du marché.  Le script ci-dessous propose un exemple de requetage de l'API de Crowdstrike via l'utilisation du module Powershell PSFalcon (https://www.powershellgallery.com/packages/PSFalcon)

L'acces et l'utilisation de l'Api Crowdstrike requiert bien sur un abonnement Crowdstrike (https://www.crowdstrike.com/)

Le script utilisant pour l'acces a l'API, une clé d'encryptage (AES.key), un fichier contenant le SecID (SecID.txt), et un fichier contenant la passphrase (pass.txt), il est necessaire de recreer ces éléments avec le contexte de l'abonnement auquel on se connecte (SecID).

Le script interroge l'API pour recuperer des éléments tel que les hotes, les comportements (Behaviors), les detections, les incidents.

 

QueryCrowdstrike.ps1 (11,62 kb)

 

##############################################
### QUERY CROWDSTRIKE WITH PSFALCON MODULE ###
##############################################


<# 

    .SYNOPSIS 
        INTERROGATION D'UN TENANT FALCON CROWDSTRIKE VIA L'UTILISATION DU MODULE POWERSHELL PSFALCON
        NB: LES DONNEES SONT EXTRAITES SOUS FORME D'UN FICHIERS CSV 

    .PARAMETER  
        ClientID : Client ID crowdstrike
        Pass : Password du compte d'acces a l'API
        
        ExportFolder : Dossier d'export du fichier CSV
        LogFolder : Chemin du dossier où creer le log du script

 
    .EXAMPLE 
     .\QueryCrowdstrike.ps1 -CloudUrl "https://api.eu-1.crowdstrike.com"  -ClientID <clientid> -Pass <pass> -ExportFolder ./ -LogFolder ./
#>


[CmdletBinding()]
param(
[Parameter(Mandatory,HelpMessage="Cloud URL")]
$CloudUrl,

[Parameter(HelpMessage="Client ID crowdstrike")]
$ClientID,

[Parameter(HelpMessage="Password du compte d'acces a l'API")]
$Pass,

[Parameter(Mandatory,HelpMessage="Dossier d'export du fichier CSV")]
[string]$ExportFolder="./CSV",

[Parameter(Mandatory,HelpMessage="Chemin du dossier où creer le log du script")] 
[string]$LogFolder="./",

[Parameter(Mandatory,HelpMessage="Chemin de la clé utilisée pour l'encryption du CID et de la passphrase")] 
$KeyFile = "D:\MyFolder\CROWDSTRIKE\AES.key",

[Parameter(Mandatory,HelpMessage="Chemin du fichier contenant le SecID du client")] 
$SecIDFile = "D:\MyFolder\CROWDSTRIKE\SecID.txt",

[Parameter(Mandatory,HelpMessage="Chemin du fichier contenant la passphrase")] 
$PassFile = "D:\MyFolder\CROWDSTRIKE\Pass.txt"


)


# TO RENEW KEY FILE USED FOR CLIENT ID AND PASSPHRASE ENCRYPTION
<#
    # Generate Key File
    $Key = New-Object Byte[] 16   # You can use 16, 24, or 32 for AES
    [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
    $Key | out-file $KeyFile

#>


# TO RENEW SECID ENCRYPTION, EXECUTE THE CODE BETWEEN <# #>

<#
    # Create secure string object
    $SecIDFile = "D:\MyFolder\CROWDSTRIKE\SecID.txt"
    $Key = Get-Content $KeyFile
    $SecID = read-host  -Prompt "Enter client SecID" -AsSecureString
    $SecID | ConvertFrom-SecureString -key $Key | Out-File $SecIDFile

#>


# TO RENEW PASSPHRASE ENCRYPTION, EXECUTE THE CODE BETWEEN <# #>

<#
    # Create secure string object
    $PassFile = "D:\MyFolder\CROWDSTRIKE\Pass.txt"
    $Key = Get-Content $KeyFile
    $Pass = read-host  -Prompt "Enter client PassPhrase" -AsSecureString
    $Pass | ConvertFrom-SecureString -key $Key | Out-File $PassFile

#>






# OTHER VARIABLES
# Script Name
$ScriptName = "QueryCrowdstrike.ps1"
# LogName = ScriptName without extension
$Log = $ScriptName.Split('.')[0]


# FUNCTIONS


function Write-Log 
{ 
    <# 
    .SYNOPSIS 
        This function creates or appends a line to a log file. 
 
    .PARAMETER  Message 
        The message parameter is the log message you'd like to record to the log file. 
 
    .EXAMPLE 
        PS C:\> Write-Log -Message 'Value1' 
        This example shows how to call the Write-Log function with named parameters. 
    #> 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory)] 
        [string]$Message,
        [Parameter(Mandatory)] 
        [string]$LogPath, 
        [Parameter(Mandatory)] 
        [string]$LogName
        
    ) 
     
    try 
    { 
        $DateTime = Get-Date -Format ‘MM-dd-yy HH:mm:ss’ 
        Add-Content -Value "$DateTime - $Message" -Path "$LogPath\$LogName.log" 
    } 
    catch 
    { 
        Write-Error $_.Exception.Message 
    } 
} 



            




# Requis si l'import du module echoue en en renvoyant plusieurs messages 'Unable to find [System.Net.Http.(...)*]' 
Add-Type -AssemblyName System.Net.Http 

# Import Module
Import-Module -Name D:\MyFolder\CROWDSTRIKE\Powershell_Module\psfalcon-master\PSFalcon.psm1



$Key = Get-Content $KeyFile

# Get file content and Decrypt ClientID
$ClientID = Get-Content $SecIDFile | ConvertTo-SecureString -Key $key
$ClientID = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ClientID))

# Get file content and Decrypt Pass
$Pass = Get-Content $PassFile | ConvertTo-SecureString -Key $key
$Pass = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Pass))







# Query for Falcon Token
try
    {
    Request-FalconToken -ClientId $ClientID -ClientSecret $Pass -Hostname $CloudUrl
    }
catch
    {
    $Message = "Error during Request-FalconToken - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }


# Test if Test-FalconToken return True
if ($(Test-FalconToken).token -eq $true)  
      {
      $Message = "Token is valid - OK"
      write-host -F Green $Message
      Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
      }
Else
    {
    $Message = "Problem with Token - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }




# GET DATA

#region Falcon Hosts 

# Get Falcon Hosts (exemple option -filter:  –Filter "hostname:'SRV'")
try
    {
    $FalconHosts = Get-FalconHost -All -Detailed
    #$FalconHosts | select hostname,os_version,agent_version,status | ft -AutoSize
    }
catch
    {
    $Message = "Problem during Get-FalconHost - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }


# Convert To CSV
 try
    {
    $FalconHostsCSV = $($FalconHosts | select `
        hostname,
        os_version,
        platform_name,
        status,
        agent_version,
        config_id_base,
        config_id_build,
        @{Name='First_Seen';Expression={[datetime]::ParseExact($_.first_seen.Replace('T','').Replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},
        @{Name='Last_Seen';Expression={[datetime]::ParseExact($_.last_seen.Replace('T','').Replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},
        reduced_functionality_mode | ConvertTo-Csv -Delimiter ',' -NoTypeInformation).Replace('"','')
    
    # Display CSV File
    $FalconHostsCSV
    }
catch
    {
    $Message = "Error during convert to CSV file for FalconHosts - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }

# Export CSV
 try
    {   
    $FalconHostsCSV | Out-File -FilePath "$ExportFolder`/FalconHosts.csv" -Force
    }
catch
    {
    $Message = "Error during export of CSV file for FalconHosts - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }


#endregion Falcon Hosts 







#region Falcon Detection




#Get-FalconDetection
write-host "FALCON DETECTION EVENTS" -B White -f Blue
try
    {
    $FalconDetection = Get-FalconDetection -Detailed -All  
    $FalconDetection | sort created_timestamp -Descending
    }
catch
    {
    $Message = "Error during Get-FalconDetection - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }


# Convert To CSV
 try
    {
    $FalconDetectionCSV = $($FalconDetection | select `
    detection_id,
    @{Name='Detection_Creation_Date';Expression={[datetime]::ParseExact($_[0].created_timestamp.split('.')[0].Replace('T',''),'yyyy-MM-ddHH:mm:ss',$null)}},
    @{Name='HostName';Expression={$_.device.hostname}},
    @{Name='HostIP';Expression={$_.device.local_ip}},
    @{Name='DeviceID';Expression={$_.device.device_id}},
    @{Name='BehaviorID';Expression={$_.Behaviors.Behavior_id}},
    @{Name='Behavior_FileName';Expression={$_.Behaviors.filename}},
    @{Name='Behavior_FilePath';Expression={$_.Behaviors.filepath}},
    @{Name='Behavior_cmdline';Expression={$_.Behaviors.cmdline}},
    status,
    max_severity_displayname,
    email_sent | ConvertTo-Csv -Delimiter ',' -NoTypeInformation).Replace('"','')
    }
catch
    {
    $Message = "Error during convert to CSV file for FalconDetection - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }

# Export CSV
 try
    {   
    $FalconDetectionCSV | Out-File -FilePath "$ExportFolder`/FalconDetection.csv"
    }
catch
    {
    $Message = "Error during export of CSV file for FalconDetection - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }




#endregion Falcon Detection




#region Falcon Behavior

# Get-FalconBehavior (NB: Transform TimeStamp to more readable format with [datetime]::ParseExact)
write-host "FALCON BEHAVIOR EVENTS" -B White -f Blue

try
    {
    $FalconBehavior = Get-FalconBehavior | foreach {Get-FalconBehavior -Ids $_} | Select -property  behavior_id,display_name,objective,@{Name='BehaviorDate';Expression={[datetime]::ParseExact($_.timestamp.Replace('T','').replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},cmdline,filepath,user_name,incident_id,tactic_id,tactic,technique_id,technique | sort BehaviorDate -Descending
    $FalconBehavior
    }
catch
    {
    $Message = "Error during Get-FalconBehavior - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }


# Convert To CSV
 try
    {
    $FalconBehaviorCSV = $($FalconBehavior | select BehaviorDate,cmdline,filepath,user_name | ConvertTo-Csv -Delimiter ';' -NoTypeInformation).Replace('"','')
    }
catch
    {
    $Message = "Error during convert to CSV file for FalconBehavior - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }

# Export CSV
 try
    {   
    $FalconBehaviorCSV | Out-File -FilePath "$ExportFolder`/FalconBehavior.csv"
    }
catch
    {
    $Message = "Error during export of CSV file for FalconBehavior - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }



#endregion Falcon Behavior





#region Falcon Incident

write-host "FALCON INCIDENTS EVENTS" -B White -f Blue
try
    {
    $FalconIncidents= Get-FalconIncident -Detailed -All  
    $FalconIncidents | sort created -Descending
    }
catch
    {
    $Message = "Error during Get-FalconIncident - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }


# Convert To CSV
 try
    {
    $FalconIncidentsCSV = $($FalconIncidents | select `
    incident_id,
    @{Name='Creation_Date';Expression={[datetime]::ParseExact($_.created.Replace('T','').Replace('Z',''),'yyyy-MM-ddHH:mm:ss',$null)}},
    state,
    email_state  | ConvertTo-Csv -Delimiter ',' -NoTypeInformation).Replace('"','')



        

    }
catch
    {
    $Message = "Error during convert to CSV file for FalconIncident - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }

# Export CSV
 try
    {   
    $FalconIncidentsCSV | Out-File -FilePath "$ExportFolder`/FalconIncidents.csv"
    }
catch
    {
    $Message = "Error during export of CSV file for FalconIncidents - END OF SCRIPT"
    write-host -F Red $Message
    Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
    EXIT 1
    }




#endregion Falcon Incident

 

Active Directory - Comment installer un module PowerShell sans connexion internet ?

Pour limiter la surface d'attaque d'un système d'information, il est courant que les serveurs n'aient pas de connexions internet. C'est un problème pour l'installation de modules PowerShell via la commande Install-Module qui va utiliser une URL internet pour télécharger ses sources. Comment peut-on alors faire pour récupérer ces précieux modules ?

 

Les messages d'erreurs type lorsque le serveur n'est pas autorisé à récupérer un module depuis internet

Message d'erreur type pour Install-Module

 

Message d'erreur type pour Get-PSRepository

 

On peut essayer de réinitialiser les paramètres par défaut du répertoire PowerShell avec la commande Register-PSRepository - Default mais une nouvelle saisie de Get-Repository démontre que rien n'a été changé.

 

Il existe également d'autre paramètres pour la commande Register-PSRepository qui nous permettent par exemple de spécifier nous-mêmes les URL de repository PowerShell mais quel que soient les paramètres entrés sans connexion internet la connexion ne sera jamais établie.

 

Sauvegarder le module PowerShell depuis un ordinateur avec une connexion internet

La commande Save-Module permet de sauvegarder un module PowerShell dans un dossier défini.

Un dossier du module téléchargé est alors dans le dossier spécifié.

Le dossier du module PowerShell doit être ensuite copié sur le serveur qui n'a pas de connexion internet. Le dossier cible doit être celui par défaut pour l'installation de module PowerShell ou s'il a été changé ce dernier.

 

Pour trouver les répertoires de modules PowerShell la variable d'environnement $env:PSModulePath peut être utilisé.

 

Habituellement, il est préférable que le module soit disponible à l'ensemble des utilisateur du serveur, le dossier C:\Program Files\WindowsPowerShell\Modules va donc être utilisé comme cible pour la copie du module PowerShell.

 

La commande Import-Module peut ensuite être utilisée pour chargé le nouveau module dans une session PowerShell. 

Power BI Report Server - Script - Export de dashboards en PBIX

Le script ci-dessous prend en paramètre un fichier contenant une liste de dashboard a exporter au format pbix.

 

#####################################################################
###### PwBI_Export_Dashboards.ps1 - EXPORT DE RAPPORTS EN PBIX ######
#####################################################################


<# 

    .SYNOPSIS 
        CONNEXION A L'API SQL POWERBI REPORTING SERVICES ET EXPORT DE UN OU PLUSIEURS DASHBOARD
 

    .PARAMETER  
        webServiceUrl : Url Racine du serveur de rapport
        CatalogUrl : Url du catalogue des items
        DashboardListFile : Fichier des noms de dashboard a exporter
        BackupFolder : Dossier d'export des dashboards
        LogFolder : Chemin du dossier où creer le log du script

 
    .EXAMPLE 
        .\PwBI_Export_Dashboards.ps1 -webServiceUrl "http://MyServer/Reports"  -DashboardListFile ".\PwBI_Export_Dashboards_List.txt" -BackupFolder ".\BACKUP" -LogFolder ".\BACKUP" 
     
#>


[CmdletBinding()]
param(
[Parameter(Mandatory,HelpMessage="Url Racine du serveur de rapport")]
[string]$webServiceUrl,

[Parameter(Mandatory=$false,HelpMessage="Url du catalogue des items")]
[string]$CatalogUrl = "$webServiceUrl/api/v2.0/CatalogItems",


[Parameter(Mandatory,
HelpMessage="Fichier des noms de dashboard a exporter")]
[ValidateScript({
if( -Not ($_ | Test-Path) ){
                throw "File does not exist"
            }
            return $true 
})]
[string]$DashboardListFile,

[Parameter(Mandatory,HelpMessage="Dossier d'export des dashboards")]
[string]$BackupFolder,

[Parameter(Mandatory,HelpMessage="Chemin du dossier où creer le log du script")]
[string]$LogFolder = "D:\Indicateurs_Securité"

)




# GET DASHBOARD LIST CONTENT
[array]$DashboardList = Get-Content -Path $DashboardListFile



# SCRIPT NAME
$ScriptName = "PwBI_Export_Dashboards.ps1"

# LogName = ScriptName without extension
$Log = $ScriptName.Split('.')[0]

# GET CREDENTIALS TO CONNECT TO REPORT SERVER
$cred = $(Get-Credential -Credential "$env:USERDOMAIN\$env:USERNAME")



function Write-Log 
{ 
    <# 
    .SYNOPSIS 
        This function creates or appends a line to a log file. 
 
    .PARAMETER  Message 
        The message parameter is the log message you'd like to record to the log file. 
 
    .EXAMPLE 
        PS C:\> Write-Log -Message 'Value1' 
        This example shows how to call the Write-Log function with named parameters. 
    #> 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory)] 
        [string]$Message,
        [Parameter(Mandatory)] 
        [string]$LogPath, 
        [Parameter(Mandatory)] 
        [string]$LogName
        
    ) 
     
    try 
    { 
        $DateTime = Get-Date -Format ‘MM-dd-yy HH:mm:ss’ 
        Add-Content -Value "$DateTime - $Message" -Path "$LogPath\$LogName.log" 
    } 
    catch 
    { 
        Write-Error $_.Exception.Message 
    } 
} 




# TABLEAU DES CATALOG ITEMS
$Message = "Recuperation du catalogue des items..."
write-host $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log


            try
            {
            $CatalogItems = Invoke-RestMethod -Uri $CatalogUrl -ContentType 'application/json' -UseDefaultCredentials -Method get
            }
            catch
            {
            $Message = "Error during query of Catalog Items"
            Write-Log -Message "$Message - $($Error[0].Exception)" -LogPath $LogFolder -LogName $Log
            Write-Host -F Yellow $Message
            exit 1
            }



# COMPARAISON DE $CatalogItems ET $ReportList POUR DETERMINER LA LISTE DES DASHBOARDS A EXPORTER

$FoundReport = $CatalogItems.value | Where-Object {$_.name -in $DashboardList}

if (!($FoundReport))
{
$Message = "The required Dashboards have not been found in the catalog of the report server - END OF SCRIPT"
write-host -f Yellow $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
Exit 1
}



# EXPORT DES DASHBOARDS
try
{

    foreach ($Report in $FoundReport)
    {
    $url = "$CatalogUrl($($Report.Id))/Content/`$value"
    Invoke-WebRequest -UseDefaultCredentials -Uri $url -OutFile "$BackupFolder\$($Report.name).pbix"
    }

}
catch
{
$Message = "KO - The required Dashboards have not been found in the catalog of the report server - END OF SCRIPT"
write-host -f Yellow $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
Exit 1
}


$Message = "OK - The required Dashboards have been Exported to $BackupFolder - END OF SCRIPT"
write-host -f Green $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log
Exit 0



 

Power BI Report Server - Script - Execution d'un plan de refresh d'un rapport

Le script ci-dessous se connecte sur l'api de Reporting Services (Power BI) pour executer le rafraichissement des données d'un rapport spécifique.

 

###### PWBI_REFRESH_PLAN.PS1 ######

<# 

    .SYNOPSIS 
        CONNEXION A L'API SQL POWERBI REPORTING SERVICES ET EXECUTION DU PLAN DE RAFRAICHISSEMENT D'UN RAPPORT SPECIFIQUE
 

    .PARAMETER  
        webServiceUrl : Url Racine du serveur de rapport
        CatalogUrl : Url du catalogue des items
        ReportFolderPath : Chemin du dossier contenant le rapport a rafraichir (NB: apres la racine du serveur de rapport)
        ReportName : Nom du dashboard a rafraichir
        RefreshPlan : nom du plan de Refresh
        LogFolder : Chemin du dossier où creer le log du script

 
    .EXAMPLE 
        .\PwBI_Refresh_Plan.ps1 -webServiceUrl "http://MyServer/Reports" -ReportFolderPath "/MySpecFolder/" -ReportName "MySpecDashboard" -RefreshPlan "Refresh_Every_2H" -LogFolder "C:\Temp"   
     
#>


[CmdletBinding()]
param(
[Parameter(Mandatory,HelpMessage="Url Racine du serveur de rapport")]
[string]$webServiceUrl,

[Parameter(Mandatory=$false,HelpMessage="Url du catalogue des items")]
[string]$CatalogUrl = "$webServiceUrl/api/v2.0/CatalogItems",

[Parameter(Mandatory,HelpMessage="Chemin du dossier contenant le rapport a rafraichir (NB: apres la racine du serveur de rapport)")]
[string]$ReportFolderPath,

[Parameter(Mandatory,HelpMessage="Nom du dashboard a rafraichir")]
[string]$ReportName,

[Parameter(Mandatory,HelpMessage="nom du plan de Refresh")]
[string]$RefreshPlan,

[Parameter(Mandatory,HelpMessage="Chemin du dossier où creer le log du script")]
[string]$LogFolder = "D:\Indicateurs_Securité"

)

# FULL REPORT PATH
$FullPath = "`'$ReportFolderPath$ReportName`'"  # Backtick to escape "'" character.

# REFRESH PLAN URL
$RefreshPlanUrl = "$webServiceUrl/api/v2.0/PowerBIReports(Path=$FullPath)/CacheRefreshPlans"


# SCRIPT NAME
$ScriptName = "PwBI_Refresh_Plan.ps1"

# LogName = ScriptName without extension
$Log = $ScriptName.Split('.')[0]

# GET CREDENTIALS TO CONNECT TO REPORT SERVER
$cred = $(Get-Credential -Credential "$env:USERDOMAIN\$env:USERNAME")



function Write-Log 
{ 
    <# 
    .SYNOPSIS 
        This function creates or appends a line to a log file. 
 
    .PARAMETER  Message 
        The message parameter is the log message you'd like to record to the log file. 
 
    .EXAMPLE 
        PS C:\> Write-Log -Message 'Value1' 
        This example shows how to call the Write-Log function with named parameters. 
    #> 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory)] 
        [string]$Message,
        [Parameter(Mandatory)] 
        [string]$LogPath, 
        [Parameter(Mandatory)] 
        [string]$LogName
        
    ) 
     
    try 
    { 
        $DateTime = Get-Date -Format ‘MM-dd-yy HH:mm:ss’ 
        Add-Content -Value "$DateTime - $Message" -Path "$LogPath\$LogName.log" 
    } 
    catch 
    { 
        Write-Error $_.Exception.Message 
    } 
} 



            




# TABLEAU DES CATALOG ITEMS
$Message = "Recuperation du catalogue des items..."
write-host $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log


            try
            {
            $CatalogItems = Invoke-RestMethod -Uri $CatalogUrl -ContentType 'application/json' -UseDefaultCredentials -Method get
            }
            catch
            {
            $Message = "Error during query of Catalog Items"
            Write-Log -Message "$Message - $($Error[0].Exception)" -LogPath $LogFolder -LogName $Log
            Write-Host -F Yellow $Message
            exit 1
            }




# RECUPERATION DU RAPPORT SPECIFIQUE
$Message = "Recuperation du rapport $ReportName"
write-host $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log


            $CatalogItem = $CatalogItems.value | Where-Object Name -eq $ReportName
            if (!($CatalogItem))
            {
            $Message = "Unable to find $ReportName"
            Write-Log -Message "$Message - $($Error[0].Exception)" -LogPath $LogFolder -LogName $Log
            Write-Host -F Yellow $Message
            exit 1
            }
 


# RECUPERATION DU PLAN DE RAFRAICHISSEMENT
$Message = "Recuperation du plan de rafraichissement"
write-host $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log


            try
            {
            $refreshplans = 
            
            Invoke-RestMethod -Uri $RefreshPlanUrl -Method get -UseDefaultCredentials
            
            }
            catch
            {
            $Message = "Error during query of Refresh Plan"
            Write-Log -Message "$Message - $($Error[0].Exception)" -LogPath $LogFolder -LogName $Log
            Write-Host -F Yellow $Message
            exit 1
            }



# RECUPERATION DE L'ID DU PLAN DE RAFRAICHISSEMENT
$refreshplanId = $($refreshplans | Where-Object {$_.value.Description -eq $refreshplan}).value.Id




# EXECUTION DU PLAN DE RAFRAICHISSEMENT
$Message = "Execution du plan de rafraichissement"
write-host $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log


            try
            {
            
            Invoke-RestMethod -Uri "$webServiceUrl/api/v2.0/CacheRefreshPlans($refreshplanId)/Model.Execute" -Method post -UseDefaultCredentials
            
            }
            catch
            {
            $Message = "Error during execution of Refresh Plan"
            Write-Log -Message "$Message - $($Error[0].Exception)" -LogPath $LogFolder -LogName $Log
            Write-Host -F Yellow $Message
            exit 1
            }

 

[Powershell] - Durcissement Windows Server 2016

Ce script permet de désactiver les éléments non essentiels au serveur lors de son installation.

##################################
# Step 1 : Network configuration #
##################################
Write-Host 'Network configuration' -ForegroundColor Green
Write-Host 'WINS configuration' -ForegroundColor Gray
$Arguments = New-Object System.Collections.Hashtable
$Arguments.Add('DNSEnabledForWINSResolution', $false)
$Arguments.Add('WINSEnableLMHostsLookup', $false)

$ErrorCode = (Invoke-CimMethod -ClassName Win32_NetworkAdapterConfiguration -MethodName EnableWINS -Arguments $Arguments).ReturnValue
If ($ErrorCode -gt 0) {
	Write-Host 'Error when disabling WINS' -ForegroundColor Red
    }

############################
# Step 2 : Remove Features #
############################

Write-Host 'Features configuration' -ForegroundColor Green
$Features = @(
    'FS-SMB1'
    )
$Features | ForEach-Object { 
    $CurrentFeature = $_
    Try {
        Uninstall-WindowsFeature -Name $CurrentFeature -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    # Release
    $CurrentFeature = $null
    }

######################################
# Step 3 : Disabling Scheduled Tasks #
######################################

Write-Host 'Scheduled Tasks configuration' -ForegroundColor Green
$ScheduledTasks = @(
    '*XblGameSaveTask*'
    '*XblGameSaveTaskLogon*'
    )
$ScheduledTasks | ForEach-Object {
    $CurrentScheduledTask = $_
    Try {
        Get-ScheduledTask -TaskName $CurrentScheduledTask | Disable-ScheduledTask -ErrorAction Stop | Out-Null
        }
    Catch {
        Write-Warning $($_)
        }
    $CurrentScheduledTask = $null
    }

################################
# Step 4: Windows Applications #
################################

Write-Host 'Windows Applications configuration' -ForegroundColor Green
$Apps = Get-AppxPackage -AllUsers | Where-Object {$_.NonRemovable -eq $false}
$Packages = Get-AppxProvisionedPackage -Online:$true

# Verifying if some Apps could be remove
If ($Apps.count -gt 0) {
    $Apps | ForEach-Object {
        $AppName = $_.Name
        Try {
            $Package = Get-AppxPackage -Name $AppName -ErrorAction Stop
            If ($Package) {
                Try {
                    # Remove App
                    Write-Host "Removing $AppName" -ForegroundColor Cyan
                    #Remove-AppPackage -Package $Package -ErrorAction Stop
                    $Package = $null
                    }
                Catch {
                    Write-Warning $($_)
                    }
                }
            Else {
                If ($Packages.Count -gt 0) {
                    # Remove the app with Online Package
                    $Package = $Packages.Where({$_.DisplayName -eq $AppName})
                    If ($Package) {
                        Try {
                            Write-Host "Removing $AppName" -ForegroundColor DarkCyan
                            Remove-AppxProvisionedPackage -PackageName $Package.PackageName -Online -ErrorAction Stop
                            }
                        Catch {
                            Write-Warning $($_)
                            }
                        }
                    }
                }
            }
        Catch {
            Write-Warning $($_)
            }
        # Release
        $AppName = $null
        }
    }

###################################
# Step 5 : OneDrive configuration #
###################################

Write-Host 'OneDrive configuration' -ForegroundColor Green
If (Get-Process -Name "*onedrive*") {
    Try {
        Get-Process -Name "*onedrive*" | Stop-Process -Force -ErrorAction Stop
        If (Test-Path -Path "$env:SystemRoot\SysWOW64\OneDriveSetup.exe") {
            Try {
                Start-Process -FilePath "$($env:SystemRoot)\SysWOW64\OneDriveSetup.exe" -ArgumentList '/uninstall' -ErrorAction Stop | out-Null
                }
            Catch {
                Write-Warning $($_)
                }
            }
        Elseif (Test-Path -Path "$env:SystemRoot\System32\OneDriveSetup.exe") {
            Try {
                Start-Process -FilePath "$($env:SystemRoot)\System32\OneDriveSetup.exe" -ArgumentList '/uninstall' -ErrorAction Stop | out-Null
                }
            Catch {
                Write-Warning $($_)
                }
            }
        }
    Catch {
        Write-Warning $($_)
        }
    }
Else {
    Write-Host "No Process OneDrive here" -ForegroundColor Cyan
    }

###################################
# Step 6 : Services configuration #
###################################

$services = @(
    'AppVClient';
    'AudioEndpointBuilder';
    'Audiosrv';
    'AxInstSV';
    'Browser';
    'bthserv';
    'CDPUserSvc';
    'CscService';
    'dmwappushservice';
    'FrameServer';
    'icssvc';
    'lfsvc';
    'lltdsvc';
    'MapsBroker';
    'NcbService';
    'NetTcpPortSharing';
    'OneSyncSvc';
    'PcaSvc';
    'PhoneSvc';
    'PrintNotify';
    'QWAVE';
    'RemoteAccess';
    'RmSvc';
    'SCardSvr';
    'ScDeviceEnum';
    'SensorDataService';
    'SensorService';
    'SensrSvc';
    'SharedAccess';
    'ShellHWDetection';
    'Spooler';
    'SSDPSRV';
    'stisvc';
    'TabletInputService';
    'tzautoupdate';
    'UevAgentService';
    'upnphost';
    'WalletService';
    'WiaRpc';
    'wisvc';
    'wlidsvc';
    'WpnService';
    'WSearch';
    'XblAuthManager';
    'XblGameSave'
    )

$services | Get-Service | Stop-Service -Force

$services | Get-Service | Set-Service -StartupType Disabled -Status Stopped

Try {
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NgcCtnrSvc" -Name "Start" -Value 0x4 -Force -ErrorAction Stop
    }
Catch {
    Write-Warning $($_)
    }
Try {
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NgcSvc" -Name "Start" -Value 0x4 -Force -ErrorAction Stop
    }
Catch {
    Write-Warning $($_)
    }
Try {
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\PimIndexMaintenanceSvc" -Name "Start" -Value 0x4 -Force -ErrorAction Stop
    }
Catch {
    Write-Warning $($_)
    }
Try {
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\UnistoreSvc" -Name "Start" -Value 0x4 -Force -ErrorAction Stop
    }
Catch {
    Write-Warning $($_)
    }
Try {
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\UserDataSvc" -Name "Start" -Value 0x4 -Force -ErrorAction Stop
    }
Catch {
    Write-Warning $($_)
    }
Try {
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\WpnUserService" -Name "Start" -Value 0x4 -Force -ErrorAction Stop
    }
Catch {
    Write-Warning $($_)
    }

$services2 = @(
    'NgcCtnrSvc';
    'NgcSvc';
    'PimIndexMaintenanceSvc';
    'UnistoreSvc';
    'UserDataSvc';
    'WpnUserService';
    )

$services2 | Get-Service | ft Name,StartType,Status

If (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NgcCtnrSvc_*") {
    Try {
        Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NgcCtnrSvc_*' -Name 'Start' -Value 0x4 -Force -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    }


If (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NgcSvc_*") {
    Try {
        Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NgcSvc_*' -Name 'Start' -Value 0x4 -Force -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    }


If (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\PimIndexMaintenanceSvc_*") {
    Try {
        Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\PimIndexMaintenanceSvc_*' -Name 'Start' -Value 0x4 -Force -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    }


If (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\UnistoreSvc_*") {
    Try {
        Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\UnistoreSvc_*' -Name 'Start' -Value 0x4 -Force -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    }


If (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\UserDataSvc_*") {
    Try {
        Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\UserDataSvc_*' -Name 'Start' -Value 0x4 -Force -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    }


If (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\WpnUserService_*") {
    Try {
        Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\WpnUserService_*' -Name 'Start' -Value 0x4 -Force -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    }

If (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\xbgm") {
    Try {
        Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\xbgm' -Name 'Start' -Value 0x4 -Force -ErrorAction Stop
        }
    Catch {
        Write-Warning $($_)
        }
    }

 

[Powershell] - Etat des lieux des licences O365

Besoin d'avoir un état des lieux de vos licences O365 (voir de l'automatiser) ?

Voici quelques lignes Powershell qui vous remontrons les informations.

Prérequis:

Vous aurez besoin de:

  • Powershell 5.1
  • Le module Azure AD

Code :

Connect-AzureAD
$Array = @()
$AllSKU = Get-AzureADSubscribedSku

$AllSKU | sort SkuPartNumber | foreach {
    $SkuPartNumber = $_.SkuPartNumber
    $Bought = $_.PrepaidUnits.enabled
    $Suspended = $_.PrepaidUnits.Suspended
    $Warning = $_.PrepaidUnits.Warning
    $Assigned = $_.ConsumedUnits
    $Rest = $Bought - $Assigned

    $Array += New-Object psobject -Property @{
        License = $SkuPartNumber
        Bought = $Bought
        Assigned = $Assigned
        Will_Expired = $Warning
        Suspended = $Suspended
        Rest = $Rest
        }
    $SkuPartNumber = $null
    $Bought = $null
    $Assigned = $null
    $Warning = $null
    $Suspended = $null
    $Rest = $null
        
    }

$Array | FT License,Bought,Assigned,Will_Expired,Suspended,Rest
$Array | Export-Csv C:\temp\Licenses.csv -Delimiter ";" -Encoding UTF8 -NoTypeInformation

 

Bien entendu, pour l'automatiser il faudra modifier l'authentification et passer par de la moderne authentification (via un SPN).

Script - API Vmware VCenter v7 - Get VM infos

Une mise a jour du script proposé récemment, utilisant la nouvelle version de l'API de Vcenter.

 

### QUERY VCENTER REST API (v7) TO GET VM LIST ###


$user = ‘myaccount’
$pswd = Read-Host -Prompt "Enter Password"
$vCenterName = ‘MyVcenter’
$encoded = [System.Text.Encoding]::UTF8.GetBytes(($user, $pswd -Join ‘:’))
$encodedPassword = [System.Convert]::ToBase64String($Encoded)
$authHeader = @{
Authorization = "Basic $($EncodedPassword)"
}
$sRest = @{
Method = ‘Post’
Uri = "https://$($vCenterName)/api/session"
Headers = $authHeader
}
$result = Invoke-RestMethod @sRest


# Get TokenID
$authHeader = @{
‘vmware-api-session-id’ = $result.value
}


# Get All Hosts
$gethosts = "https://$($vCenterName)/api/vcenter/host"
$resultgethost = Invoke-RestMethod -Uri $gethosts -Headers $authHeader
$hostidlist = $resultgethost.value.host


# For each host, get all VMs

foreach ($hostid in $hostidlist)
{
$get_vm = "https://$($vCenterName)/rest/vcenter/vm?filter.hosts=$hostid"
$resultvm = Invoke-RestMethod -Uri $get_vm -Headers $authHeader
[array]$FinalTableau += $resultvm
}

# Display Result
$FinalTableau.value | select name,power_state


# Output to CSV
$CsvTab = $FinalTableau.value | select name,power_state | ConvertTo-Csv -Delimiter ';' -NoTypeInformation
$CsvTab | Out-File .\VMList.csv

 

 

Powershell : Comparer une date manuellement saisie avec un format spécifique à la date du last logon d'un utilisateur dans Active Directory

Dans le cadre de l'automatisation, il arrive de recevoir une demande pour développer un script PowerShell pour le nettoyage ou la gestion de l'obsolescence des utilisateurs dans l'Active Directory.

Dans le script, vous aurez peut être besoin de comparer la date du last logon utilisateur dans l'Active Directory avec une date manuellement saisie (variable du script) avec un format spécifique.

Ci-dessous un exemple de PowerShell pour comparer une date donnée avec une date de last logon utilisateur dans Active Directory :

# Import Active Directory Module
Import-Module ActiveDirectory
 
#Set a fixed date for comparison
$Fixed_Date = "13/11/2021"
 
#Convert the fixed date from a string to a compatible specific format
$Fixed_Date_Convert = [datetime]::parseexact($Fixed_Date, 'dd/MM/yyyy', $null)  
 
#Get AD user last logon date in dd/MM/yyyy format
$ADUser = get-aduser "jdoe" -Properties lastlogondate | select @{Name=”ModifiedLastLogonDate”;Expression={$_.LastLogonDate.ToString(“dd/MM/yyyy”)}}
 
#Convert AD last logon date to a specific format to be compared with the chosen date above
$ADdate = [datetime]::parseexact($ADUser.ModifiedLastLogonDate, 'dd/MM/yyyy', $null)
 
if($ADdate -le $Fixed_Date_Convert)
    {
        echo "Active directory last logon date is inferior to the fixed date"
        }
    else
    {
        echo "Active directory last logon date is superior to the fixed date"
        }

Conclusion:

La méthode [datetime]::parseexact(dateString, format, provider) Convertit la représentation sous forme de chaîne spécifiée d'une date et d'une heure en son équivalent DateTime.

PowerShell - Convertir les signes diacritiques

Un signe diacritique ou diacritique est un élément ajouté à une lettre, par exemple dans la langue française, les biens connus : à, é, ç mais également les ł, ø, ß utilisés dans d'autres langues. La plupart des logiciels ne sont pas capables de traiter les diacritiques correctement ce qui peut avoir pour conséquence une simple gêne utilisateur ou dans le pire des cas des accès non fonctionnels.

Comment alors se débarrasser de ces diacritiques ? Hors de question de les retirer complétement, car ils font partie intégrante des mots, il faut alors essayer de les convertir vers des caractères connus par les logiciels. 

 

La fonction de conversion des diacritiques

function Convert-Diacritic #Fonction qu'il faudra appeler pour convertir le diacritique
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est facultatif
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null, s'il est obligatoire
        [string]$InputString #Paramètre qui attend la chaîne de caractères qui contient les diacritiques à convertir
    )

    Begin 
    {
        $Return = @{} #Tableau de retour qui contient la chaîne de caractères sans diacritiques
        
        $DiacriticsArray = @{ #Hashtable, aussi appelé tableau de conversion dans ce script, qui contient à droite du signe égal le caractère avec diacritique et à gauche du signe égale, le caractère cible post conversion
            #Par exemple à deviendra a après conversion
            #Pour déterminer vers quel caractère convertir un diacritique, une simple recherche internet peut être utilisé
            a = 'à', 'á', 'â', 'ã', 'ā', 'ă', 'ą'
            aa = 'å'
            ae = 'ä', 'æ'
            c = 'ç', 'ć', 'ĉ', 'ċ', 'č'
            d = 'ď', 'đ'
            e = 'è', 'é', 'ê', 'ë', 'ē', 'ĕ', 'ė', 'ę', 'ě'
            g = 'ĝ', 'ğ', 'ġ', 'ģ'
            h = 'ĥ', 'ħ'
            i = 'ì', 'í', 'î', 'ï', 'ĩ', 'ī', 'ĭ', 'ı', 'į'
            ij = 'ij'
            j = 'ĵ'
            k = 'ķ', 'ĸ'
            l = 'ĺ', 'ļ', 'ľ', 'ŀ', 'ł'
            n = 'ñ', 'ń', 'ņ', 'ň', 'ŋ'
            o = 'ò', 'ó', 'ô', 'õ', 'ō', 'ŏ', 'ő'
            oe = 'ö', 'ø', 'œ'
            r = 'ŕ', 'ŗ', 'ř'
            s = 'ś', 'ŝ', 'ş', 'š'
            ss = 'ß'
            t = 'ţ', 'ť', 'ŧ'
            th = 'þ'
            u = 'ù', 'ú', 'û', 'ũ', 'ů', 'ū', 'ŭ', 'ű', 'ų'
            ue = 'ü'
            w = 'ŵ'
            y = 'ý', 'ÿ', 'ŷ'
            z = 'ź', 'ż', 'ž'
        }
    }

    Process
    {
        $OutputString = $InputString.ToLower() #Transforme tous les caractères majuscules de la chaîne de caractères d'entrée en minuscule
        #Le tableau ne peut convertir que les diacritiques minuscules, cela simplifie également la maintenabilité du tableau de conversion et du code

        foreach ($Letter in $DiacriticsArray.GetEnumerator()) #On parcourt chaque paire lettres/diacritiques du tableau de conversion
        #La méthode GetEnumerator permet de générer deux propriétés Key et Value pour chaque paire du tableau de conversion, ci-après appelé $Letter.Value et $Letter.Key
        {
            $DiacriticsLetter = $Letter.Value #Letter.Value contient l'ensemble des diacritiques d'une paire (ligne) du tableau de conversion
            foreach ($Diacritic in $DiacriticsLetter) #On parcourt chaque diacritique d'une ligne
            {
                if ($OutputString -match $Diacritic) #Si le diacritique qui est en train d'être parcouru est contenu dans la chaîne de caractères d'entrée, le code suivant sera exécuté
                {
                    $OutputString = $OutputString.Replace($Diacritic, $Letter.Key) #Le diacritic qui en train d'être parcouru est remplacé par le caractère cible de conversion contenu dans la propriété $Letter.Key 
                }
            }
        }

        #La boucle précédente va donc répéter les actions décrites précédemment pour chaque paire et chaque diacritique du tableau de conversion

        $Return.outputStringObject = $OutputString #Attribution de la chaîne de caractères sans diacritiques à la variable de sortie
        Return $Return #Retourne la chaîne de caractères sans diacritiques
    }
}

 

Exemple d'utilisation de la fonction de conversion

Le script suivant appelle la fonction de conversion de diacritique lorsque lui-même est appelé

. .\Convert-Diacritic_article.ps1 #Permet de déclarer (dot source) la fonction de conversion de diacritique pour qu'elle puisse être utilisée

$String = Convert-Diacritic -InputString "DébutăîœăßøFin" #Appelle de la fonction de conversion de diacritique et lui passe en paramètre une chaîne de caractères qui contient des diacritiques 

$String.outputStringObject #La chaîne de caractères sans diacritiques est contenu dans la propriété outputStringObject, elle est donc appelée pour afficher le résultat

 

Appel du script précédent

PS D:\A_folder> .\Just_call_me_already.ps1 #Appel du script précédent qui contient l'appelle de la fonction de conversion de diacritique
debutaioeassoefin #Les diacritiques dans la chaîne de caractères ont été convertis selon les règles du tableau de conversion 

 

Remarque : les scripts qui manipulent des diacritiques, tels que les scripts ci-avant, doivent être encodés avec du BOM, par exemple UTF-8 with BOM, sans quoi les diacritiques seront mal convertis par l'IDE (integrated development environment) et empêcheront la bonne exécution du code.

PowerShell - Déchiffrer un mot de passe

Comme vu dans l'article Powershell - Chiffrer un mot de passe la santé de votre équipe de sécurité a été préservé car vos mots de passe sont désormais chiffrés dans vos scripts. Un mot de passe chiffré c'est bien mais comment le déchiffrer pour pouvoir l'utiliser ?

 

La fonction de déchiffrement

function Get-SecureStringFromEncryptedFile #Fonction qu'il faudra appeler pour déchiffrer le mot de passe
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est obligatoire
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null
        [string]$Name, #Paramètre qui attend le nom de l'utilisateur, il est utilisé pour créer un credential object

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$PwdPath #Paramètre qui attend le chemin complet du fichier qui contient le mot de passe chiffré
    )

    Begin 
    {
        $Return = @{} #Tableau de retour qui contient le mot de passe sous forme de secure string et le credential object généré à partir du nom du compte de service et de son mot de passe
    }

    Process
    {
        $PwdSecureString = Get-Content $PwdPath | ConvertTo-SecureString #Récupére le mot de passe chiffré depuis le fichier txt fourni et le convertit en secure string
        $Return.pwdSecureString = $PwdSecureString #Attribution de la secure string générée dans la variable de sortie de la fonction

        $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Name, $PwdSecureString #Génére un credential object à partir de l'utilisateur et de son mot de passe
        $Return.credentials = $Credentials #Attribution du credential object générée dans la variable de sortie de la fonction

        Return $Return #Retourne le mot de passe ainsi que la secure string en sortie de la fonction
    }
}

 

 

Exemple d'utilisation de la fonction de déchiffrement

. .\Get-SecureStringFromEncryptedFile_article.ps1 #Permet de déclarer (dot source) la fonction de chiffrement pour qu'elle puisse être utilisée

$Password = Get-SecureStringFromEncryptedFile -Name "Svc-test-01" -PwdPath "D:\A_folder\Svc-test-01_encrypted_password.txt" #Appelle de la fonction de déchiffrement et lui passe en paramètre le nom de l'utilisateur le chemin complet du fichier qui contient le mot de passe chiffré

#Le mot de passe sous forme de secure string est conservé dans la propriété pwdSecurestring, on peut y accéder comme ceci $Password.pwdSecureString
#Le credential object qui contient le jeu d'identifiant nom d'utilisateur et mot de passe est conservé sous forme de credential object dans la propriété credentials, on peut y accéder comme ceci $Password.credentials

$Credentials = $Password.Credentials #Attribution du credential object à la variable $Credentials
Get-ADUser -Identity "Toto" -Credential $Credentials #Utilisation de la cmdlet Get-ADUser avec le credential object précédemment généré

 

Remarque : lorsque le fichier est généré, une combinaison du compte utilisateur et du compte machine est utilisée. Cela implique que le mot de passe ne peut être déchiffré que par l'utilisateur qui l'a chiffré et sur la machine sur laquelle le chiffrement a eu lieu.