Question [Astuce] Implémenter la fonctionnalité -AsJob
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
Réduire
Plus d'informations
- Messages : 6300
- Remerciements reçus 68
il y a 9 ans 4 mois #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 , 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
- Vous êtes ici :
- Accueil
- forum
- PowerShell
- Contributions à la communauté
- [Astuce] Implémenter la fonctionnalité -AsJob