Question Un comportement inattendu sur le retour de commande

Plus d'informations
il y a 1 an 6 mois #32656 par CesarX
Bonjour à tous!
Pour contextualiser un peu, je réalise depuis plusieurs mois un script d'automatisation d'actions dans le cadre de mon travail (technicien système et réseau)
L'une des actions que mon script propose, c'est d'afficher la liste de partages disponibles sur un serveur, en fonction d'un terme souhaité, puis afficher les partages contenant ce terme dans leur nom, et la liste des ACL (samaccountname + droits associés)
Jusqu'ici tout allait bien.
Lorsque j'ai voulu ajouter le nom et prénom ça a été le drame. Le displayname n'étant pas disponible directement dans l'ACL, j'ai voulu créer mon propre pscustomobject pour récupérer d'une part le samaccountname et le droit NTFS, et d'autre part le DisplayName (récupéré sur l'AD grâce au IdentityReference de l'ACL) bref... je pense que ce n'est pas très important
Merci de ne pas lever les yeux au ciel en lisant mon code, je ne fais pas de la revente !
# On demande quel terme rechercher dans les partages
$terme=read-host("Quoi rechercher ? ");

# On recupere les resultats dans $partajs01
$partajs01=invoke-command -cn serveur -scriptblock{param($terme); get-wmiobject -class win32_share | ?{$_.type -eq 0} | select pscomputername,name,path | ?{$_.path -match $terme}} -argumentlist $terme;

# On recupere la liste des utilisateurs pour associer IdentityReference de l'ACL au DisplayName de l'AD
$listUsrs=get-aduser -filter * -properties samaccountname,displayname | select samaccountname,displayname;

# J'initialise mon objet qui contient tout ça puis j'ajoute ce qu'il faut
$objets=@();
foreach($partaje in $partajs01){
    $pathou=('\\'+$partaje.pscomputername+'\'+($partaje.path).replace(':','$')).tostring();
    $asseeelles=(get-acl -path $pathou).access;
    foreach($asseeelle in $asseeelles){
        $dN=($listUsrs | ?{$_.samaccountname -eq ($asseeelle.IdentityReference.value -replace ".*\\","")} | select -expand displayname);
        $objets+=[pscustomobject]@{SharePath=$pathou;IdentityReference=$asseeelle.IdentityReference.value;Displayname=$dN;FileSystemRights=$asseeelle.FileSystemRights;};
    }
}
$chemins=$objets | sort sharepath -unique | select -expand sharepath;
foreach($chemin in $chemins)
{
    write-host ("`r`n`r`n$chemin`r`n---------------");
    $objets | ?{$_.sharepath -eq $chemin} | select IdentityReference,Displayname,FileSystemRights;
}

Comportement attendu : avoir les chemins d'accès aux partages dont le nom contient un terme (genre, \\serveur\disque$\chemin\du\partage\comptabilite), (comptabilite etant par exemple le terme recherché)
ET, en dessous de chacun de ces chemins, un tableau avec IdentityReference, DisplayName, FileSystemRights
Quand on lit le code il n'y a pas de doute (dernier foreach), les ACL sont filtrées après l'affichage de chaque chemin (variable $objets en dessous du write-host $chemin)
Mais en fait je n'ai pas du tout ça au résultat... lorsque j'exécute le script (même en le collant dans un invite), mes ACL sont affichées à la fin, toutes d'un bloc... why the phoque ?
Dernière anecdote, si par exemple je termine mon script par un "pause", powershell attends que je saisisse quelque chose pour afficher $objets avant de se fermer. Alors qu'en fait au moment du pause, le foreach est terminé, la variable est censée avoir été affichée depuis belle lurette
Honnêtement, je trouve cela très dérangeant, plusieurs fois j'ai utilisé [pscustomobject] et le retour se fait lorsque souhaité
Savez-vous pourquoi ce résultat ?

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

Plus d'informations
il y a 1 an 6 mois #32658 par Christophe MELIN
C'est un problème lié à la sortie utilisée.
La ligne write-host envoie directement à l'écran alors que la ligne $objets | ?{$_.sharepath -eq $chemin} | select IdentityReference,Displayname,FileSystemRights retourne des objets qui sont envoyés par défaut dans le pipeline de sortie et ce pipeline n'est affiché que à la fin du script.

Pour régler ton problème :
  • soit tu remplaces write-host par write-output
  • soit tu ajoutes  | ft -auto à la fin de la ligne $objets | ?... car ft veut dire Format-Table qui envoie par défaut vers la sortie écran (comme write-host)
Si tu essaies la première solution avec une pause , tu n'auras plus aucun affichage tant que tu n'auras pas appuyer sur ENTREE
Si tu essaies la seconde solution, tout sera affiché avant la pause

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

Plus d'informations
il y a 1 an 6 mois #32669 par CesarX
Bonjour Christophe et merci pour ta réponse !
Effectivement le format-table résout bien mon problème (l'affichage est effectué lorsqu'il est demandé)
J'utilise souvent le pipeline de sortie du genre "$variable | blabla | blablabla" sans ft, et je ne constate jamais ce comportement car le retour est effectué quand demandé et le script continue normalement.
J'ai du mal à comprendre pourquoi dans ce cas précis le comportement change..
En tout cas merci pour la réponse !

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

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