PI Services

Le blog des collaborateurs de PI Services

Active Directory : Restaurer des objets de la corbeille sous 2008

Quand on a l'habitude d'utiliser la console Active Directory Administrative Center pour restaurer des objets AD et que l'on désire restaurer des objets AD sur un Active Directory sous Windows server 2008, on peut se sentir décontenancer.

Eh oui pas de console ADAC sur Windows Server 2008, bon alors on fait quoi ? Powershell !!!

Pour lister tous les objets de la corbeille :

# List All Deleted objects
$AllDeletedObjects = Get-ADObject -ldapFilter:"(msDS-LastKnownRDN=*)" –IncludeDeletedObjects -Properties *

Ensuite libre à vous de filtrer sur les types d'objets, nom et autres propriétés.

# List All Deleted Groups
$DeletedGroups = $AllDeletedObjects | Where {$_.ObjectClass -eq "group"}

Et enfin restaurer ce qui vous intéresse dans l'OU de destination qui convient (ici le groupe "GS-Office-E3" restaurer dans l'OU "RestaurationPlace")

$ToRestore = $DeletedGroups | Where {$_.Name -like "GS-Office-E3"}
$DeletedGroups | Restore-ADObject -TargetPath "OU=RestorationPlace,DC=Demo,DC=corp"

 

Powershell : Générateur de mot de passe

Vous en avez marre de chercher un nouveau mot de passe, ou vous devez générer des mots de passe pour u grand nombre d'utilisateur ?

Voici quelques lignes Powershell que vous pouvez utiliser dans une fonction ou  dans une boucle pour générer un mot de passe.

$TinyCharacters = "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"
$CapitalCharacters = "A",",B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
$NumeralCharacters = "0","1","2","3","4","5","6","7","8","9"
$SpecialCharacters = "!","$","%","&","/","(",")","=","?","}","]","[","{","@","#","*","+"
$Password = $null

1..3 | ForEach-Object {
    $Password += Get-Random -Minimum 1 $TinyCharacters
    $Password += Get-Random -Minimum 1 $CapitalCharacters
    $Password += Get-Random -Minimum 1 $NumeralCharacters
    $Password += Get-Random -Minimum 1 $SpecialCharacters
    }
$Password

Ces quelques ligne vous permettront de générer un mot de passe de 12 caractères, pour un mot de passe plus long changez la valeur de 1..3 à 1..4 ou 1..5

SCOM - Comprendre la supervision des erreurs réseau

Un client m’a récemment demandé comment fonctionnait techniquement la supervision des erreurs sur les ports réseau, et il m’a fallu un peu d’analyse pour lui fournir une réponse complète.

Commençons par le début : cette supervision est assurée par les moniteurs High Output et High Input Error Rate.

La lecture du Knowledge associé fournit quelques informations, mais reste assez floue :

This monitor enters a warning state when the percentage of output packet errors is greater than the error threshold configured for this interface (the default is 10%). The output packet error percentage is derived by dividing the number of output packets in error by the total number of output packets. The result of this calculation is expressed as a percentage and compared to the error threshold.

On y apprend donc que le moniteur réagit à un pourcentage d’erreur supérieur à 10%, et que ce taux est calculé en divisant le nombre de paquets en erreur par le nombre de paquets total.

Très bien, mais d’où proviennent ces informations ? Pour le savoir, il va falloir comme souvent aller regarder ce qui se passe dans le code.

On y constate en premier lieu que ces moniteurs ne s’appuient non pas sur deux OIDs (« nombre total de paquets » et « paquets en erreur »), mais sur 6 OIDs pour le moniteur Input et 4 OIDs pour le moniteur Output :

<OIDifHCInUcastPkts>.1.3.6.1.2.1.31.1.1.1.7.$Target/Property[Type="NetworkLibrary!System.NetworkManagement.NetworkAdapter"]/Index$</OIDifHCInUcastPkts>

<OIDifHCInMulticastPkts>.1.3.6.1.2.1.31.1.1.1.8.$Target/Property[Type="NetworkLibrary!System.NetworkManagement.NetworkAdapter"]/Index$</OIDifHCInMulticastPkts>

<OIDifHCInBroadcastPkts>.1.3.6.1.2.1.31.1.1.1.9.$Target/Property[Type="NetworkLibrary!System.NetworkManagement.NetworkAdapter"]/Index$</OIDifHCInBroadcastPkts>

<OIDifInDiscards>.1.3.6.1.2.1.2.2.1.13.$Target/Property[Type="NetworkLibrary!System.NetworkManagement.NetworkAdapter"]/Index$</OIDifInDiscards>

<OIDifInErrors>.1.3.6.1.2.1.2.2.1.14.$Target/Property[Type="NetworkLibrary!System.NetworkManagement.NetworkAdapter"]/Index$</OIDifInErrors>

<OIDifInUnknownProtos>.1.3.6.1.2.1.2.2.1.15.$Target/Property[Type="NetworkLibrary!System.NetworkManagement.NetworkAdapter"]/Index$</OIDifInUnknownProtos>



Une rapide recherché dans une base de MIB nous indique que ces OIDs remontent les valeurs suivantes :

  • Nombre de paquets Unicast
  • Nombre de paquets Multicast
  • Nombre de paquets Broadcast
  • Nombre de paquets Discarded (input seulement)
  • Nombre de paquets en Erreur
  • Nombre de paquets d’un protocole inconnu (input seulement).

Et également qu’il s’agit du nombre total de paquets transmis depuis le démarrage de l’équipement réseau.

Comment SCOM fait-il donc pour agglomérer ces données et en ressortir un pourcentage ?

Voyons maintenant un peu plus loin dans le code, du côté du module ConditionDetection System.NetworkManagement.NetworkAdapter.InputErrorRate.ifMIB.

Il repose principalement sur une ConditionDetection de type Network.Computation, qui permet des expressions assez copieuses :

clip_image002

Nous nous intéresserons ici à trois éléments en particulier, les champs DeltaValue et les expressions BranchValueExpression et Summation/Division/Product

Delta Value

Ces éléments permettent de travailler non pas sur la valeur absolue renvoyée depuis l’OID, mais plutôt sur la valeur de son augmentation depuis la mesure précédente.
Autrement dit, si le moniteur vérifie toutes les 10 minutes la valeur de l’OID et que cette dernière est d’abord « 1000 » puis, 10 minutes plus tard, « 1500 », alors la valeur de l’expression DeltaValue sera la différence entre 1500 et 1000, soit 500.

Cela permet au moniteur de superviser une variation du taux d’erreur lors du dernier intervalle de mesure uniquement, et pas en se basant sur des valeurs « diluées » depuis le démarrage du device.

 BranchValueExpression
clip_image003

Probablement le champ qui m’a donné le plus de fil à retordre, il est composé de trois sous-blocs :

<SimpleExpression>

<TrueValueExpression>

<FalseValueExpression>



Son fonctionnement est en réalité assez simple : l’expression comprise dans SimpleExpression est évaluée en premier et, en fonction de si elle est Vraie ou Fausse, le workflow continue par l’évaluation de l’expression True ou False.

Ce mécanisme est utilisé ici pour déterminer une propriété du moniteur (IsMib2SNMP) et moduler le fonctionnement en conséquence puis plus loin pour éviter les « divisions par 0 ».

Sumation/Division/Product

Ces expressions sont celles qui vont réellement produire le résultat qui nous intéresse, le taux d’erreur sur le port réseau.

Dans un premier temps, les valeurs obtenues pour toutes les OIDs (Unicast/Multicast/Broadcast/Discard/Error/Unknown) vont être additionnées (Summation) pour obtenir le total de paquets transmis :
clip_image005

Puis le nombre de paquets en erreur va être divisé (Division) par le total obtenu juste avant, et enfin cette dernière valeur sera multipliée (Product) par 100 :

clip_image007

De cette facon, on a bien comme résultat final le pourcentage de paquets en erreur lors du dernier intervalle de mesure.

Script - Modification du fichier host et test de la resolution a distance

Le script ci-dessous propose de remplacer a distance le contenu du fichier de resolution c:\windows\system32\etc\hosts et d'effectuer un test de resolution des nouveaux noms.

Remote_ModifyHostFiles_And_Test.ps1 (3,61 kb)

# SCRIPT TO MODIFY HOSTS FILE ON TARGET SERVER AND REMOTELY TEST RESOLUTION

Param(
$SrvList = ("Srv1","Srv2"),
$HostFilePath = "C:\Windows\System32\drivers\etc\hosts",
$cred = $(Get-Credential -Credential MyDomain\Me),
$Host1 = "Host1",
$IP1 = "0.0.0.1",
$Host2 = "Host2",
$IP2 = "0.0.0.2"
)


$cred = $(Get-Credential -Credential MyDomain\Me)




# host file
$hostcontent = 
"# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	::1             localhost


# MY SERVERS
$Host1     $IP1
$Host2     $IP2
"


# FUNCTIONS
function Spec-Ping
{
Param($HostToPing)
Try {
            Test-Connection -ComputerName $HostToPing -Count 1 -ErrorAction Stop
            } 
            Catch [System.Net.NetworkInformation.PingException]
            {
            $pingresult = "PING ERROR TO $HostToPing - CHECK NAME RESOLVING"
            }

}


# OPENING WINRM SESSIONS ON MGS SERVERS
$SrvList | foreach {


            try
            {
            New-PSSession -Name $($_.Substring(0,13)) -ComputerName $_ -Credential $cred
            }
            catch
            {
            write-host -F red "Erreur lors de la creation de la session Winrm vers $_"
            }

}





$sessions = Get-PSSession

Foreach ($sess in $sessions)
    {
        
        Invoke-Command -Session $sess -ScriptBlock {Param($hostcontent,$HostFilePath) Set-Content -Path $HostFilePath -value $hostcontent} -ArgumentList $hostcontent,$HostFilePath
    
}



Write-Host "`n--- PING RESULT:"

Foreach ($sess in $sessions) 
    {
        
        # First Host Test
        $pingresult = Invoke-Command -Session $sess -ScriptBlock ${Function:Spec-Ping} -ArgumentList $Host1
            
            
            
             switch -Wildcard ($pingresult.value)
             {
             "PING ERROR*" {write-host -ForegroundColor red $pingresult.value}
             }
             

             Switch ($pingresult.IPV4Address.IPAddressToString)
                {
                $IP1 {Write-Host "OK -- $Host1 is resolved by "$sess.ComputerName" to $IP1"}
                default {Write-Host "KO - Unable to get resolution of $Host1 on"$sess.ComputerName""}
                }
    



        
         # Second Host Test
         $pingresult = Invoke-Command -Session $sess -ScriptBlock ${Function:Spec-Ping} -ArgumentList $Host2
         switch -Wildcard ($pingresult.value)
             {
             "PING ERROR*" {write-host -ForegroundColor red $pingresult.value}
             }
             

             Switch ($pingresult.IPV4Address.IPAddressToString)
                {
                $IP2 {Write-Host "OK -- $Host2 is resolved by "$sess.ComputerName" to $IP2"}
                default {Write-Host "KO - Unable to get resolution of $Host2 on"$sess.ComputerName""}
                }

    }     




#Remove Pssessions
Remove-PSSession *