Question Snapshot systeme

Plus d'informations
il y a 13 ans 11 mois #11532 par SiSMik
Snapshot systeme a été créé par SiSMik
Bonjour,

Aujourd'hui je suis en train de finaliser un script qui crée une image des composants importants d'un server windows en production.

Ce script doit permettre de valider que les fichiers vitaux et les configurations essentielles n'ont pas changés suite à l'installation d'un logiciel. Donc je le lance une fois avant et une fois après, puis je compare les deux ficheirs XML.

Je suis parti du principe qu'il fallait checker les points suivants:
    Les services
    Le dernier reboot
    Les utilisateurs et leurs groupes respectifs
    La configuration des cartes réseaux
    Les tables de routage
    Les règles du firewall
    Les disques dur
    les Updates Windows
    Le contenu des ficheirs suivants (et leur hash MD5) : \"$env:windir\security\",
    \"$env:windir\System32\config\", \"$env:windir\System32\drivers\", \"$env:windir\System32\Setup\"

Suite à ça je lance la commande: [code:1]sfc /verifyonly [/code:1]

J'ai rencontré plusieurs problèmes que j'ai contourné, mais le plus gros soucis c'est au niveau des règles de Firewall, avec les différents profiles HNetCfg.FwMgr ne permet pas réellement de lister toutes les règles sur Windows 2008R2 alors que sur 2003 si.
J'ai donc parsé la clef de registre qui contient ses informations sur 2008 et pour 2003 je crée l'objet firewall.

Si vous avez des idées pour rendre ça meilleur au niveau du firewall et si quelqu'un qui maitrise le format XML aussi pouvait me dire si mon fichier de sortie est correct :)

Pour vous donner une idée:
[code:1]# ---
#
# Date : 10/04/2012
# Version : 1.0
#
# Comments : This script provides an \"image of Windows System before truning the VM in Run Mode and give Administrator Access to the client
# It lists differents arguements and properties of the server in order to validate the integrity later
#
# ---

# --- Begin Script params

$VerbosePreference = \"Continue\"

# --- End of script params

# --- Begin of variables declarate

$XMLFile = \"C:\sysinfo.xml\"

$LogDir = \"c:\log\\"
$Log = \"GetSysInformation.log\"
$LogFile = \"$LogDir\" + \"$Log\"

# --- End of variables declarate

# --- Begin of function declaration

function Write-Log {
param([string]$ID,[string]$Status,[string]$Reason)
$CurrentDate = date -Format \"dd/MM/yyyy HH:mm:«»ss :\"
Write-Verbose -Message \"$CurrentDate $Status : $Reason \"
echo \"$CurrentDate $Status : $Reason \" >> $logfile
if ($Status -eq \"ERROR\"«») {
if ($error) {
$error >> $LogFile
$error.clear()
}
exit $ID
}
}

# --- End of function declaration

# --- Script Body
Try {
if (-not (test-path $LogDir)) {new-item -type directory -path $LogDir}
if (-not (test-path $LogFile)) {new-item -type file -path $LogFile}
}
Catch { Write-Log -ID \"001\" -Status \"ERROR\" -Reason \"Create Log File\" }

Write-Log -ID \"001\" -Status \"SUCCESS\" -Reason \"Create Log File\"

echo '<?xml version=\"1.0\"?>' >> $XMLFile
echo ' <Services>' >> $XMLFile

# --- List all services and status
Try { $Service = @() }
Catch { Write-Log -ID \"002\" -Status \"ERROR\" -Reason \"Initialize Services array.\" }
Try {
Write-Log -ID \"002\" -Status \"SUCCESS\" -Reason \"Initialize Services array.\"
Get-Service | % {
$a = ' <Service Name=\"' + $_.Name + ' Status=\"' + $_.Status + '\">' + $_.Name + '</Service>'
echo $a >> $XMLFile
}
}
Catch { Write-Log -ID \"003\" -Status \"ERROR\" -Reason \"Populate Services and store informations in XML File.\" }

Write-Log -ID \"003\" -Status \"SUCCESS\" -Reason \"Populate Services and store informations in XML File.\"

echo ' </Services>' >> $XMLFile
echo ' <System>' >> $XMLFile

# --- Check if computer has reboot
# --- Check at first the reboot time
Try {
$wmi = Get-WmiObject -Class Win32_OperatingSystem
$Reboot_time = $wmi.ConvertToDateTime($wmi.LastBootupTime)
}
catch { Write-Log -ID \"004\" -Status \"ERROR\" -Reason \"Get the last Reboot Time\" }

Write-Log -ID \"004\" -Status \"SUCCESS\" -Reason \"Get the last Reboot Time\"

# --- Check the last logon
Try {
$entry = Get-EventLog -After $Reboot_time -LogName Security | Where-Object {($_.EventID -eq '4624') -and ($_.EntryType -eq 'SuccessAudit')} | Select-Object -First 1
if ($wmi.Version -lt 6) { $entry = Get-EventLog -LogName Security | Where-Object {($_.EventID -eq '528') -and ($_.EntryType -eq 'SuccessAudit')} | Select-Object -First 1 }
$lastLogon = $entry.TimeGenerated
}
catch { Write-Log -ID \"005\" -Status \"ERROR\" -Reason \"Get the last Logon Time\" }

Write-Log -ID \"005\" -Status \"SUCCESS\" -Reason \"Get the last Logon Time\"

# --- Populate the sysinfo array
Try {

$a = \" <Computer Name=\" + $env:computername + \">\"
$b = \" <LastBoot>\" + $Reboot_time + \"</LastBoot>\"
$c = \" <LastLogon>\" + $lastLogon + \"</LastLogon>\"

echo $a >> $XMLFile
echo $b >> $XMLFile
echo $c >> $XMLFile
echo \" </Computer\" >> $XMLFile

echo ' </System>' >> $XMLFile
echo ' <Users>' >> $XMLFile
}
Catch { Write-Log -ID \"006\" -Status \"ERROR\" -Reason \"Populate SysInformations and store informations in XML File.\" }

Write-Log -ID \"006\" -Status \"SUCCESS\" -Reason \"Populate Sysinformations and store informations in XML File.\"

# --- List all users and thier respectiv group(s)
Try {
$user = @()
$adsi = [ADSI]\"WinNT://$env:COMPUTERNAME\"
$adsi.Children | where {$_.SchemaClassName -eq 'user'} | Foreach-Object {
$groups = $_.Groups() | Foreach-Object {$_.GetType().InvokeMember(\"Name\", 'GetProperty', $null, $_, $null)}
$_ | Select-Object @{n='UserName';e={$_.Name}},@{n='Groups';e={$groups -join ';'}}
} | % {
$a = ' <User Name=\"' + $_.UserName + '\" Groups=\"' + $_.Groups + '\">' + $_.UserName + '</User>'
echo $a >> $XMLFile
}
}
Catch { Write-Log -ID \"007\" -Status \"ERROR\" -Reason \"Populate Users informations and store informations in XML File.\" }

Write-Log -ID \"007\" -Status \"SUCCESS\" -Reason \"Populate Users informations and store informations in XML File.\"

echo ' </Users>' >> $XMLFile
echo ' <nics>' >> $XMLFile

# --- get IP Infos
Try {
$nic = @()
gwmi Win32_NetworkAdapterConfiguration | Where-Object { $_.IpAddress -match \".\"} | % {
[String]$IPAddress = $_.IpAddress[0]
if ($wmi.Version -lt 6) {[String]$IPAddress = $_.IpAddress}
[String]$SubnetMask = $_.IPSubnet[0]
if ($wmi.Version -lt 6) {[String]$SubnetMask = $_.IPSubnet}
$a = ' <Nic Name=\"' + $_.ServiceName + '\" SubNetMask=\"' + $SubnetMask + '\" DefaultGateway=\"' + $_.DefaultIPGateway + '\" DNSServers=\"' + $_.DNSServerSearchOrder + '\" MACAddress=\"' + $_.MACAddress + '>' + $IPAddress + '</Nic>'
echo $a >> $XMLFile
}
}
Catch { Write-Log -ID \"008\" -Status \"ERROR\" -Reason \"Populate nics and store informations in XML File.\" }

Write-Log -ID \"008\" -Status \"SUCCESS\" -Reason \"Populate nics informations and store informations in XML File.\"

echo ' </nics>' >> $XMLFile
echo ' <Routes>' >> $XMLFile

# --- get Routes
Try {
$i = 0
$routes = @()
gwmi win32_IP4RouteTable | % {
$i++
$a = ' <Route Number=\"' + $i + '\" Destination=\"' + $_.Destination + '\" SubnetMask=\"' + $_.Mask + '\" DefaultGateway=\"' + $_.NextHop + '\">' + $i + '</Route>'
echo $a >> $XMLFile
}
}
Catch { Write-Log -ID \"009\" -Status \"ERROR\" -Reason \"Populate Routes and store informations in XML File.\" }

Write-Log -ID \"009\" -Status \"SUCCESS\" -Reason \"Populate Routes informations and store informations in XML File.\"

echo ' </Routes>' >> $XMLFile
echo ' <FWRules>' >> $XMLFile

Try {
$Firewall = New-Object -com HNetCfg.FwMgr
if ($firewall.localpolicy.CurrentProfile.FirewallEnabled) {

# --- Get Firewall rules
$k = 0
$FWRules = @()
if ($wmi.Version -gt 6) {
[string]$Reg_rules = Get-ItemProperty \"HKLM:\SYSTEM\ControlSet001\services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\" | Select-String \"|\"
[array]$rules = $Reg_rules.split(\";\"«»)
foreach ($rule in $rules) {
[String]$rule_string = $rule
$rule_array = $rule_string.split(\"|\"«»)
if (($rule_array -match \"Action=\"«») -and ($rule_array -match \"Active=\"«») -and ($rule_array -match \"Dir=\"«») -and ($rule_array -match \"Protocol=\"«») -and ($rule_array -match \"Profile=\"«») -and ($rule_array -match \"LPort=\"«») -and ($rule_array -match \"App=\"«»)) {
[String]$Action = $rule_array[1]
$Action = $Action.Replace(\"Action=\", \"\"«»)
[String]$Active = $rule_array[2]
$Active = $Active.Replace(\"Active=\", \"\"«»)
[String]$Direction = $rule_array[3]
$Direction = $Direction.Replace(\"Dir=\", \"\"«»)
[String]$Protocol = $rule_array[4]
$Protocol = $Protocol.Replace(\"Protocol=\", \"\"«»)
foreach ($tmp in $rule_array) {
if ($tmp -match \"Profile=\"«») { $Profile = $tmp.Replace(\"Profile=\", \"\"«») }
elseif ($tmp -match \"LPort=\"«») { $Port = $tmp.Replace(\"LPort=\", \"\"«») }
elseif ($tmp -match \"App=\"«») { $Application = $tmp.Replace(\"App=\", \"\"«») }
}
$k++
$b = ' <Rule ID=\"' + $k + '\" Action=\"' + $Action + '\" Active=\"' + $Active + 'Direction=\"' + $Direction + '\" Protocol=\"' + $Protocol + '\" Profile=\"' + $Profile + '\" Port=\"' + $Port + '\">' + $Application + '</Rule>'
echo $b >> $XMLFile

}
}
} elseif ($wmi.Version -lt 6) {
$firewall.localpolicy.CurrentProfile.GloballyOpenPorts | % {
$k++
$b = ' <Rule ID=\"' + $k + '\" Action=\"Allow\" Active=\"' + $_.Enabled + 'Direction=\"In\" Protocol=\"' + $_.Protocol + '\" Profile=\"' + $_.Builtin + '\" Port=\"' + $_.Port + '\">' + $_.Name + '</Rule>'
echo $b >> $XMLFile
}
}
} else {
$b = ' <Firewall Status=\"OFF\">The Firewall Is Disable</Firewall>'
echo $b >> $XMLFile
}
}
Catch { Write-Log -ID \"010\" -Status \"ERROR\" -Reason \"Populate Firewall Rules and store informations in XML File.\" }

Write-Log -ID \"010\" -Status \"SUCCESS\" -Reason \"Populate Firewall Rules and store informations in XML File.\"

echo \" </FWRules>\" >> $XMLFile
echo ' <Disks>' >> $XMLFile

# --- Gest disks information
Try {
$disks = @()
gwmi win32_volume | % {
$b = [Math]::Round($_.Capacity/1024/1024/1024, 1)
$c = [Math]::Round($_.FreeSpace/1024/1024/1024, 1)
$d = ' <Disk Letter=\"' + $_.Driveletter + '\" Label=\"' + $_.label + '\" DriveType=\"' + $_.DriveType + '\" Capacity=\"' + $b + '\" FreeSpace=\"' + $c + '\">' + $_.Driveletter + '</Disk>'
echo $d >> $XMLFile
}
}
Catch { Write-Log -ID \"011\" -Status \"ERROR\" -Reason \"Populate Disks informations and store informations in XML File.\" }

Write-Log -ID \"011\" -Status \"SUCCESS\" -Reason \"Populate Disks informations and store informations in XML File.\"

echo ' </Disks>' >> $XMLFile
echo ' <Hotfixes>' >> $XMLFile

# --- Windows Updates

Try {
$updates = @()
gwmi Win32_QuickFixEngineering | % {
if ($_.Hotfixid -eq \"File 1\"«») { }
else {
$a = ' <HotFix ID=\"' + $_.Hotfixid + '\" Label=\"' + $_.Description + '\">' + $_.Hotfixid + '</HotFix>'
echo $a >> $XMLFile
}
}
}
Catch { Write-Log -ID \"012\" -Status \"ERROR\" -Reason \"Populate Hotfixes informations and store informations in XML File.\" }

Write-Log -ID \"012\" -Status \"SUCCESS\" -Reason \"Populate Hotfixes informations and store informations in XML File.\"

echo ' </Hotfixes>' >> $XMLFile
echo ' <SystemFiles>' >> $XMLFile

Try {
$WindirFiles = @()
$Directories = @(\"$env:windir\security\",\"$env:windir\System32\config\",\"$env:windir\System32\drivers\",\"$env:windir\System32\Setup\"«»)
Foreach ($dir in $Directories) {
Get-ChildItem $dir -recurse -ErrorAction SilentlyContinue | % {
if ([System.IO.DirectoryInfo] -eq $_.GetType()) {
$type = \"Directory\"
$MD5Hash = \"NoHash\"
}
else {
$error.Clear()
$type = \"File\"
Try {
[string]$file = ($_.psparentpath + \"\\" + $_).replace(\"Microsoft.PowerShell.Core\FileSystem::\",\"\"«»)
$algo = [System.Security.Cryptography.HashAlgorithm]::Create(\"MD5\"«»)
$stream = New-Object System.IO.FileStream($file, [System.IO.FileMode]::Open) -ErrorAction SilentlyContinue
$md5StringBuilder = New-Object System.Text.StringBuilder -ErrorAction SilentlyContinue
$algo.ComputeHash($stream) | % { [void] $md5StringBuilder.Append($_.ToString(\"x2\"«»)) }
$MD5Hash = $md5StringBuilder.ToString()
$stream.Dispose()
}
catch { $MD5Hash = \"Refused\" }
}
$a = ' <File Name=\"' + $_.Name + '\" LastAccessTime=\"' + $_.LastAccessTime + '\" LastWriteTime=\"' + $_.LastWriteTime + '\" Length=\"' + $_.Length + '\" Type=\"' + $type + '\">' + $MD5Hash + '</Disk>'
echo $a >> $XMLFile
}
}
}
Catch { Write-Log -ID \"012\" -Status \"ERROR\" -Reason \"Populate Integrity File informations and store informations in XML File.\" }

Write-Log -ID \"012\" -Status \"SUCCESS\" -Reason \"Populate Integrity File informations and store informations in XML File.\"

echo ' </SystemFiles>' >> $XMLFile
echo ' <VerifySystem>' >> $XMLFile

Try { $a = sfc /verifyonly }
catch { Write-Log -ID \"013\" -Status \"ERROR\" -Reason \"Execution of System Files Check.\" }

if (($a -match \"aucune violation d'intégrité\"«») -or ($a -match \"did not find any\"«»)) {
Write-Log -ID \"013\" -Status \"SUCCESS\" -Reason \"Execution of System Files Check.\"
$b = ' <System Status=\"Valid\"></System>'
echo $b >> $XMLFile
}

echo ' </VerifySystem>' >> $XMLFile[/code:1]

Bonne journée !

Message édité par: benduru, à: 17/04/12 11:30<br><br>Message édité par: benduru, à: 17/04/12 13:39

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

Plus d'informations
il y a 13 ans 11 mois #11577 par SiSMik
Réponse de SiSMik sur le sujet Re:Snapshot systeme
Pour info j'utilise cette commande à la suite pour comparer les deux fichiers qui ressortent.

[code:1]compare (gc $XMLFileBefore) (gc $XMLFile) | ? { $_.SideIndicator -eq \&quot;=&gt;\&quot; } | ft InputObject -auto[/code:1]

Je sais le -eq \&quot;=&gt;\&quot; c'est moche mais au moins ça conserve les modifications que dans un sens en sortie :)

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

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