2016-08-18 1 views
0

J'interroge environ 280 serveurs XenApp. Voici mes questions.Les requêtes WMI sont longues

$bootupMemory = gwmi -Query "SELECT * FROM Win32_OperatingSystem" -ComputerName $srv 
#$cpuLoad  = gwmi -Query "SELECT * FROM Win32_Processor" -ComputerName $srv 
#$tSessions = gwmi -Query "SELECT * FROM Win32_TerminalService" -ComputerName $srv 
$ima   = gwmi -Query "SELECT * FROM Win32_Service WHERE name='imaservice'" -ComputerName $srv 
$mfcom  = gwmi -Query "SELECT * FROM Win32_Service WHERE name='mfcom'" -ComputerName $srv 
$ctxPrintMgr = gwmi -Query "SELECT * FROM Win32_Service WHERE name='cpsvc'" -ComputerName $srv 
$msmqstatus = gwmi -Query "SELECT * FROM Win32_Service WHERE name='msmq'" -ComputerName $srv 

$cDrive  = gwmi -Query "SELECT * FROM Win32_Logicaldisk WHERE deviceid='c:'" -ComputerName $srv 
$dDrive  = gwmi -Query "SELECT * FROM Win32_Logicaldisk WHERE deviceid='d:'" -ComputerName $srv 
$loginStatus = gwmi -Query "SELECT loginsenabled, numberofsessions FROM Metaframe_Server" -Namespace root\citrix -ComputerName $srv 
$load   = gwmi -Query "SELECT * FROM Metaframe_Server_loadlevel" -Namespace root\citrix -ComputerName $srv 

Pouvez-vous me suggérer si c'est optimal ou puis-je l'optimiser. Également comment incorporer un paramètre de délai d'attente avec chaque requête. Est-ce possible?

+1

WMI, il y a seulement tellement que vous pouvez le faire avant que la vraie réponse est beaucoup de multi-threading. J'ai un système absurde qui répand ce genre de chose sur plusieurs serveurs avec 100 threads chacun pour que je puisse tirer des données de quelques milliers de serveurs dans un délai raisonnable. Avez-vous regardé Start-Job et ses amis pour commencer? –

+0

Comment fonctionne start-job, je veux dire qu'il fonctionne simultanément sur les 280 serveurs. Aidez-moi aussi à répondre à ceci: MON code se trouve dans un partage de fichiers distant. Est-ce que start-job a besoin d'un fichier local sur chaque serveur ou peut-il gérer un script sur un partage distant? – user183932

Répondre

5

L'exécution de plusieurs requêtes pour la même classe sur le même hôte n'est certainement pas optimale. Vous pouvez optimiser votre code dans une certaine mesure, en fusionnant les WHERE clauses de requêtes pour la même classe:

SELECT * FROM Win32_Service WHERE name='imaservice' OR name='mfcom' OR name='cpsvc' OR name='msmq' 

Cependant, puisque vous avez encore besoin d'interroger plusieurs classes différentes, je vous recommande d'utiliser le code tout sur l'hôte distant et renvoyer le résultat sous la forme d'un objet personnalisé:

$result = Invoke-Command -ComputerName $srv -ScriptBlock { 
    New-Object -Type PSObject -Property @{ 
    computername = $env:COMPUTERNAME 
    bootupMemory = gwmi -Query "SELECT * FROM Win32_OperatingSystem" 
    #cpuLoad  = gwmi -Query "SELECT * FROM Win32_Processor" 
    #tSessions = gwmi -Query "SELECT * FROM Win32_TerminalService" 
    ima   = gwmi -Query "SELECT * FROM Win32_Service WHERE name='imaservice'" 
    mfcom  = gwmi -Query "SELECT * FROM Win32_Service WHERE name='mfcom'" 
    ctxPrintMgr = gwmi -Query "SELECT * FROM Win32_Service WHERE name='cpsvc'" 
    msmqstatus = gwmi -Query "SELECT * FROM Win32_Service WHERE name='msmq'" 
    cDrive  = gwmi -Query "SELECT * FROM Win32_Logicaldisk WHERE deviceid='c:'" 
    dDrive  = gwmi -Query "SELECT * FROM Win32_Logicaldisk WHERE deviceid='d:'" 
    loginStatus = gwmi -Query "SELECT loginsenabled, numberofsessions FROM Metaframe_Server" -Namespace root\citrix 
    load   = gwmi -Query "SELECT * FROM Metaframe_Server_loadlevel" -Namespace root\citrix 
    } 
} 

Run Invoke-Command pour chaque serveur dans un job séparé pour exécuter les requêtes en parallèle et de réduire ainsi le temps de traitement global.

Start-Job -ScriptBlock { 
    Invoke-Command -ComputerName $args[0] -ScriptBlock { 
    New-Object ... 
    } 
} -ArgumentList $srv 

Get-Job | Wait-Job | Receive-Job 

ou (comme Mathias suggéré dans les commentaires)

Invoke-Command -ComputerName $srv -AsJob -ScriptBlock { 
    New-Object ... 
} 

Get-Job | Wait-Job | Receive-Job 
+2

Invoke-Command a même un commutateur «-AsJob» pour rendre la vie plus facile! –

+0

J'essaie d'exécuter invoke-command avec -asjob, mais je ne reçois aucun résultat $ serversRaw = qfarm/load $ hostnames = pour ($ i = 3; $ i -lt $ serversRaw.length; $ i ++) {($ serversRaw [$ i] -split "") [0]} if (($ result = Read-host "Entrez soit c: soit D: [par défaut est C:]") -eq '') {$ lecteur = "C:"} else {$ lecteur = $ résultat} icm -computer $ noms d'hôtes {gwmi -cl win32_logicaldisk | ? {$ _. deviceid -eq $ lecteur} | sélectionnez la taille, l'espace libre, pscomputername} -asjob # $ x | receive-job receive-job – user183932

+0

@ user183932 Si vous avez une nouvelle question ou une question de suivi: postez une nouvelle question. Si vous avez trouvé ma réponse utile pour résoudre le problème décrit dans cette question: veuillez considérer [l'accepter] (http://meta.stackoverflow.com/a/5235). –