Question [Astuce] Implémenter la fonctionnalité -AsJob

Plus d'informations
il y a 9 ans 4 mois #18417 par Laurent Dardenne
Le script suivant permet d'implémenter la fonctionnalité -Asjob.
C'est une adaptation de ce post .
[code:1]
#Script implémentant -Asjob
#From blog.start-automating.com/updates/Adding...werShell%20function/
<#
.Synopsis
Une fonction de test.

.EXAMPLE
$job=FaitqqChose -Name \"Shell\" -Count 951 -AsJob
Sleep -s 2
receive-job $job -Keep

#>
[OutputType([Nullable],[Management.Automation.Job])]
param(
$Name,

$Count,

# Exécute cette fonction dans un background job
[Switch]
$AsJob
)
#Fontion utilisée pour les tests uniquement
function Convert-DictionnaryEntry($Parameters)
{ #Converti un DictionnaryEntry en une string \"clé=valeur clé=valeur...\"
\"$($Parameters.GetEnumerator()|% {\"$($_.key)=$($_.value)\"})\"
}#Convert-DictionnaryEntry


#
Code création du job
#Construction du code du job
#puis exécution d'un job
if ($AsJob) {
$CommandType=$Myinvocation.MyCommand.CommandType
if (($CommandType -eq 'Function') -or ($CommandType -eq 'ExternalScript'))
{
$null = $psBoundParameters.Remove('AsJob')
$Code=$null

$MyCommandName=$Myinvocation.MyCommand.Name
if ($CommandType -eq 'Function')
{
if ($MyInvocation.MyCommand.ModuleName -ne [string]::Empty)
{ Write-Warning \"Attention la fonction '$MyCommandName' est hébergée dans un module.\" }
}
else
{ $MyCommandName=$Myinvocation.MyCommand.Name -replace '\.ps1$',''}

#Construit, à partir de l'exécution de ce code, le code à passer au job
# On crée une fonction puis l'appel à la fonction
#
#Un script est transformé en une fonction
$Code=[ScriptBLock]::Create(@\"
param([Hashtable]`$parameter)
function $MyCommandName {
$(
if ($CommandType -eq 'Function')
{Get-Command $MyCommandName | Select-Object -ExpandProperty Definition}
else
{
\"# $($Myinvocation.MyCommand.Definition)`r`n\"
Get-Command $Myinvocation.MyCommand.Definition | Select-Object -ExpandProperty ScriptContents
}
)
}
#Lors de l'exécution du job: Appel la fonction avec les paramètres reçus
$MyCommandName @parameter
\"@
)#Create

#Passe au job les paramètres SAUF le paramètre AsJob
#On propage donc les arguments recus de la ligne de commande au job
Start-Job -ScriptBlock $Code -ArgumentList $psBoundParameters
#Fin on renvoi un job
}
else
{ Throw \"Le type de commande '$CommandType' n'est pas supporté.\" }

return
}


#
Code du traitement
Write-host \"Résultat du traitement en tant que job.\"
Write-host \"Ce traitement en tâche de fond a reçu les paramètres suivants :`r`n@{$(Convert-DictionnaryEntry $PSBoundParameters )}\"
[/code:1]
Un appel séquentiel
[code:1]
.\AsJobScript.ps1 -Name 'test' -Count 10
[/code:1]
Un appel en tant que BackgroundJob :
[code:1]
$job=.\AsJobScript.ps1 -AsJob -Name 'test' -Count 10
Receive-Job $job
[/code:1]
Contenu du code généré :
[code:1]
(get-Job -id $job.id).Command
[/code:1]
On peut également placer ce code dans une fonction, qu'elle ait ou non un bloc process.
En cas de présence du bloc process la limite est justement qu'il n'y ait pas ;-), le paramètre -ThrottleLimit restant à implémenter.
Attention aux dépendances de code et au fait que dans ce cas la variable $Myinvocation sera différente.
Dans le job, on peut récupérer le nom du répertoire du script via $Myinvocation.MyCommand.Definition, sous réserve d'ajouter la génération d'une variable dans le code du scriptblock.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.065 secondes
Propulsé par Kunena