Question 2011 Scripting Games : Advanced Event 2

Plus d'informations
il y a 14 ans 10 mois #9585 par Matthew BETTON
Bonsoir,

Ci-après le script que j'ai posté lors des Scripting Games 2011, dans le cadre de l'Advanced Event 2.

Le scénario était le suivant :

You are on the server team for a large metropolitan bank and you have been tasked by the team lead to produce a detailed report about services and dependent services. Specifically, your team lead wants you to report what services are currently running on each server. In addition, the team lead wants to see what dependent services each running service has and whether or not the dependent services are also running. All of your teams servers are running Windows Server 2008 R2, and your domain contains one server running Active Directory Domains Services (AD DS) on Windows Server 2008 R2. The remaining domain controllers are either Windows Server 2008 or Windows Server 2003.

For the purposes of this scenario, it is not necessary to write the results to a file, but the script should include the capability to run against multiple remote machines. The remote machine names should not be hard-coded, but they should come from a text file, Microsoft Excel spreadsheet, database, or AD DS. Because you are on the server team, you should not bother querying desktop machines. Your report should include only services that are running, but the report of dependent services should include all services regardless of whether they are running or not. Therefore, your output might look something like the output that is shown here.


Mon script :

[code:1]#
# 2011 Scripting Games : Advanced Event 2
# Script : Get-DependentServices.ps1
# Synopsis : Use PowerShell to Identify Status of Service Dependencies
# Author : Matthew BETTON (France / Basse-Normandie / Manche (50))
#
# Prerequisites :
# - We assume this script is used with a user account that has sufficient admin rigths on all targeted computers
# - The 'ActiveDirectory' module, from RSAT, is needed (When '-ADDS' switch is used)
#

# This advanced function is suitable to incorporate into a module
Function Get-DependentServices(){

# Function parameters declaration block
[CmdletBinding(DefaultParameterSetName=\"ComputersFromList\"«»)]
param(
[Parameter(Mandatory=$true,ParameterSetName=\"ComputersFromList\"«»)]
$Filepath,
[Parameter(Mandatory=$true,ParameterSetName=\"ComputersFromAD\"«»)]
[Switch] $ADDS,
[Parameter(ParameterSetName=\"ComputersFromAD\"«»)]
[Switch]$ServersOnly=$true,
[Parameter(Mandatory=$true,ParameterSetName=\"FromOneComputer\"«»)]
[String]$ComputerName
)

# If '-ADDS' switch parameter is used, we need to collect all Windows computers from AD
if($ADDS){
# Now, we try to load ActiveDirectory Module
if(-not (Get-Module ActiveDirectory)){
try{
Import-Module ActiveDirectory -ErrorAction Stop
}
catch{
Write-Host \"Can't load ActiveDirectory Module... Exiting !\" -ForegroundColor Red
exit
}
}
# If switch '-ServersOnly' is used (by Default) we get all Windows servers in AD DS, otherwise querying for all Windows computers
if($ServersOnly){
$MyComputersList = Get-ADComputer -filter {operatingSystem -like \"*windows*server*\"} | ForEach-Object{$_.Name}
}
else{
$MyComputersList = Get-ADComputer -filter {operatingSystem -like \"*windows*\"} | ForEach-Object{$_.Name}
}

$CptList = $MyComputersList
}
# '-FilePath' parameter has been used
if($Filepath){
if(!(Test-Path $Filepath)){
Write-Host \"The file $Filepath can not be found !\" -ForegroundColor Red
exit
}
else{
# We get the computers list from a file, excluding empty lines
$CptList = Get-Content $Filepath | Where-Object{$_.Trim() -ne [System.String]::Empty}
}
}
# '-ComputerName' parameter has been used
if($ComputerName){
$CptList = @($ComputerName)
}

# This 2 variables will be used to show state of progress
# Total of numbers computers
$nbcomputers = $CptList.Count
# Initialize counter
$i = 0

# Starting to collect informations for each computer in the lit
foreach($Computer in $CptList){

# Calculate percentage of completion
[int]$count = ($i / $nbcomputers) * 100
# Display a progress bar
Write-Progress -Activity \"Collecting informations from $nbcomputers computer(s)...\" -PercentComplete $count -CurrentOperation \"processing on $Computer\" -Status \"Please wait ($count %)\"

# Gets running services on targeted computer and format the data
try{
$svc = Get-Service -ComputerName $Computer -ErrorAction Stop | Where-Object{$_.Status -eq \"Running\"} `
| Select-Object Name, @{Name=\"DependentServices\";Expression={$_.DependentServices | select-object Name, Status}}
}
catch{
Write-Error \"Could not get running services on $computer from Get-Service Cmdlet : $($Error[0].Exception.Message)\"
# Update $i before to continue to the next computer, in order to increase progress bar
$i ++
# Continue to the next computer
Continue
}

# Format the output before human reading :«»)
$infos = $svc | ForEach-Object{
Write-Output \"Service Name : $($_.Name)\"
if($_.DependentServices){
$DS = $_.DependentServices | Format-Table -HideTableHeaders -AutoSize
Write-Output $DS
}
else{
Write-Output \"(There is no dependent service for '$($_.Name)')\"
Write-Output \"`n\"
}
}

# Now we redirect computer informations to the output
$Date = (Get-Date).ToString(\"MM/dd/yyyy\"«»)
Write-Output \"\"
Write-Output \"
\"
Write-Output \">> Running services on $computer ($Date):\"
Write-Output \"
\"
Write-Output $infos

# Update $i before to continue to the next computer, in order to increase progress bar
$i++

}

}

# This command should be used in order to get Running Services
# on each Windows server found in Active Directory
Get-DependentServices -ADDS

# This command can be used in order to get Running Services on a computers list file
# Get-DependentServices -Filepath '.\Computers.txt'

# This command can be used in order to get Running Services on one computer
# Get-DependentServices -ComputerName Fabrikam01[/code:1]

Pour les personnes que cela intéresse, voici le lien vers la solution de l'expert .

Toutes les remarques seront les bienvenues !

;)

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

Plus d'informations
il y a 14 ans 10 mois #9586 par Matthew BETTON
Pour information, voici les remarques de Ed Wilson, à propos de mon script :

I am glad to see you using parametersets. You could simplify some of your error handling by using try / catch / finally. I am glad you used write-output instead of write-host, but in reality you need not do either. Also you could / should seperate your output formatting from your basic function. IE, your function should return an object, not strings. You can then create a different function to format the output IF YOU need to do so. Otherwise, just rely upon the default format* cmdlets ... or other default output.


Effectivement, je ne sais pas pourquoi je susi parti dans un délire avec les \"write-output\".

Ma fonction aurait du retourner un objet ou un tableau d'objets. Libre à l'utilisateur de cette fonction de formater ensuite le résultat...

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

Plus d'informations
il y a 14 ans 10 mois #9591 par Laurent Dardenne
Pour le Write-Output, le pb est qu'il écrit dans le pipe ou à l'écran, là le Write-Host n'écrit que sur l'écran.
Ses remarques sur la construction d'objet et sur le formatage sont justes, en même temps on peut écrire sur la console, mais cela ne doit pas être un résultat du traitement.
C'est, à mon avis, ce que confirme l'usage des cmdlets Write-Warning, ou Write-Verbose. Et je ne pense pas qu'ils écrivent dans un stream dédié.

Voir aussi cette demande .

Tutoriels PowerShell

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

Plus d'informations
il y a 14 ans 10 mois #9592 par Laurent Dardenne
Matthew BETTON écrit:

Effectivement, je ne sais pas pourquoi je suis parti dans un délire avec les \"write-output\".

Bah tu fais comme l'expert :P
J'ai un peu de mal à comprendre les remarques de E.W en consultant la solution de l'expert :silly:

Tutoriels PowerShell

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

Plus d'informations
il y a 14 ans 10 mois #9600 par Matthew BETTON
B)

En fait, j'ai cherché à obtenir le même résultat que dans la capture d'écran du scénario... Je n'ai pas compris comment c'était possible et je suis finalement parti sur du 'Write-Output', uniquement pour 'coller' au plus prêt :blush:

Le scénario

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

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