Question [Astuce] Implémenter la fonctionnalité -AsJob
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6298
- Remerciements reçus 68
il y a 9 ans 1 semaine #18417
par Laurent Dardenne
Tutoriels PowerShell
[Astuce] Implémenter la fonctionnalité -AsJob a été créé 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.
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

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.049 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- [Astuce] Implémenter la fonctionnalité -AsJob