Le site vient d'atteindre les 50000 hits. Cette dernière année fut très difficile pour mon petit blog.
En juillet 2017 le site devient "powershell.sekki.fr". Cette manœuvre qui me semblait anodine était
en réalité loin de l'être. Il m a fallu batailler ferme pour re-indexer et reconstruire le SEO du site. Cela m'a appris beaucoup de chose sur le fonctionnement du référencement
de Google. J'ai également étendu la visibilité du site en l'enregistrant auprès de Symantec car sans cela le site n'était pas accessible depuis certaine société. La non
plus cela n'a pas été une mince affaire. Mon ancien hébergeur publiait du contenu bloqué par Symantec sur mon nom de
domain. J'ai dû me résoudre à
changer d'hébergeur pour enfin me débarrasser des pages bloquées. Aujourd'hui tous ces problèmes semblent enfin réglés. Le mois d'octobre
2018 fait partie des 3 meilleurs mois depuis le lancement du site.
jeudi 15 novembre 2018
mercredi 24 octobre 2018
Grille de données
L'objet "DataGridView" est un contrôle à la fois très intéressant et beaucoup plus complexe que les autres contrôles que nous avons vu précédemment. J'ai donc réaliser un exemple avec un maximum de chose intéressante, tout en gardant un niveau que j’espère abordable pour un maximum de monde.
La façon simple et rapide de réaliser un DataGridView est d'utiliser la commande "Out-GridView". Par exemple : Get-ADComputer -Filter 'Name –Like "*"' | Out-GridView
C'est bien mais si je veux l’intégrer dans un formulaire ce n'est pas très beau, et le comportement n'est pas forcement adapté. Pour pouvoir intégrer correctement le contrôle dans un formulaire, j'utilise donc l'objet "DataGridView". Celui-ci me permet d'utiliser ses paramètres pour obtenir le résultat et la forme que je souhaite. Par exemple : $gridA1.ReadOnly permet d'autoriser (ou non) la modification des données.
#Fenêtre.
$formA = New-Object Windows.Forms.Form
$formA.Size = New-Object Drawing.Point 400,230
$formA.Text = "DataGridView"
$formA.BackColor = [System.Drawing.Color]::FromArgb(255,240,240,240)
#Taille de la fenêtre.
$largeurA = $formA.width
$hauteurA = $formA.height
#DataGrid - Options générales.
#SelectionMode -> CellSelect, FullRowSelect, FullColumnSelect,
#SelectionMode -> RowHeaderSelect, ColumnHeaderSelect.
#ScrollBars ----> None, Horizontal, Vertical, Both.
$gridA1 = New-Object System.Windows.Forms.DataGridView
$gridA1.Location = New-Object Drawing.Point -1,-1
$gridA1.Size = New-Object Drawing.Point ($largeurA-14),($hauteurA-72)
$gridA1.ScrollBars = "Vertical"
$gridA1.ReadOnly = $false
$gridA1.AutoSize = $false
$gridA1.GridColor = "Black"
$gridA1.AllowUserToResizeRows = $true
$gridA1.BorderStyle = [System.Windows.Forms.BorderStyle]::None
$gridA1.BackgroundColor = [System.Drawing.Color]::FromArgb(255,240,240,240)
$gridA1.DefaultCellStyle.SelectionBackColor = [System.Drawing.Color]::FromArgb(255,94,191,212)
$gridA1.SelectionMode = "FullRowSelect"
$gridA1.MultiSelect = $false
#DataGrid - Style de l'entête.
#ColumnHeadersHeightSizeMode -> EnableResizing, DisableResizing, AutoSize.
#ColumnHeadersBorderStyle ----> Custom, Single, Raised, Sunken, None.
$gridA1.RowHeadersVisible = $false
$gridA1.ColumnHeadersVisible = $true
$gridA1.ColumnHeadersHeightSizeMode = "DisableResizing"
$gridA1.EnableHeadersVisualStyles = $false
$gridA1.ColumnHeadersDefaultCellStyle.BackColor = [System.Drawing.Color]::FromArgb(255,44,40,109)
$gridA1.ColumnHeadersDefaultCellStyle.ForeColor = "White"
$gridA1.ColumnHeadersDefaultCellStyle.Alignment = "MiddleCenter"
$gridA1.ColumnHeadersBorderStyle = "Single"
#DataGrid - Ajouter les colonnes.
[void]$gridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$gridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$gridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewComboBoxColumn))
#DataGrid - Ajouter le texte des entêtes de colonnes.
$gridA1.Columns[0].Name = "Titre"
$gridA1.Columns[1].Name = "Editeur"
$gridA1.Columns[2].Name = "Nb Volume"
#DataGrid - Données pour la ComboBox.
$gridA1.Columns[2].DataSource = @("1","2","3","4","5","6","7","8","9","10","11","12")
$gridA1.Columns[2].FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
#DataGrid - Options des colonnes.
#SortMode -> NotSortable, Automatic, Programmatic.
foreach($column in $gridA1.Columns)
{
$column.SortMode = "NotSortable"
$column.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::Fill
}
#DataGrid - Alignement.
#Alignment -> NotSet, TopLeft, TopCenter, TopRight, MiddleLeft, MiddleCenter,
#Alignment -> MiddleRight, BottomLeft, BottomCenter, BottomRight.
$gridA1.Columns[2].DefaultCellStyle.Alignment = "MiddleCenter"
#DataGrid - Taille de colonne.
#En mode "Fill", il faut laisser une colonnes sans taille fixe.
$gridA1.Columns[2].Width = 80
#DataGrid - Ajouter les lignes de données.
[void]$gridA1.Rows.Add("Jumbor" ,"Kana" ,"2" )
[void]$gridA1.Rows.Add("Battle Game" ,"Doki-Doki" ,"2" )
[void]$gridA1.Rows.Add("Re:Teen" ,"Doki-Doki" ,"3" )
[void]$gridA1.Rows.Add("Imotep" ,"Kioon" ,"10")
[void]$gridA1.Rows.Add("Pluto" ,"Kana" ,"8" )
#Bouton - Annuler.
$buttonA1 = New-Object Windows.Forms.Button
$buttonA1.Location = New-Object Drawing.Point ($largeurA-102),($hauteurA-67)
$buttonA1.Size = New-Object Drawing.Point 80,23
$buttonA1.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$buttonA1.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
$buttonA1.Text = "Quitter"
$buttonA1.Add_Click({ $formA.Close() })
#Bouton - Valider.
$buttonA2 = New-Object Windows.Forms.Button
$buttonA2.Location = New-Object Drawing.Point ($largeurA-187),($hauteurA-67)
$buttonA2.Size = New-Object Drawing.Point 80,23
$buttonA2.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$buttonA2.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
$buttonA2.Text = "OK"
$buttonA2.Add_Click({
#Index de la 1er cellule selectionné.
$r = $gridA1.SelectedCells[0].RowIndex
$c = $gridA1.SelectedCells[0].ColumnIndex
#Nombre de ligne de données.
$n = ($gridA1.RowCount - 1)
#Si la ligne sélectionné est valide.
if (($r -ne $n) -and (![string]::IsNullOrEmpty($r)))
{
#Afficher les données.
$titre = $gridA1.SelectedCells[0].Value
$editeur = $gridA1.SelectedCells[1].Value
$volume = $gridA1.SelectedCells[2].Value
Write-Host $titre "-" $editeur "-" $volume "volume(s)."
}
else
{
#Sinon afficher une erreur.
Write-Host "La valeur sélectionné n'est pas valide."
}
})
#Lier.
$formA.Controls.Add($gridA1)
$formA.Controls.Add($buttonA1)
$formA.Controls.Add($buttonA2)
#Events.
$formA.Add_Load({
$gridA1.ClearSelection()
$formA.Activate()
})
$formA.Add_Resize({
#Ajuste la position des contrôles lorsque la fenêtre change de taille.
$gridA1.Size = New-Object Drawing.Point ($formA.width-14) ,($formA.height-72)
$buttonA1.Location = New-Object Drawing.Point ($formA.width-102),($formA.height-67)
$buttonA2.Location = New-Object Drawing.Point ($formA.width-187),($formA.height-67)
})
#Afficher.
[void]$formA.ShowDialog()
$formA = New-Object Windows.Forms.Form
$formA.Size = New-Object Drawing.Point 400,230
$formA.Text = "DataGridView"
$formA.BackColor = [System.Drawing.Color]::FromArgb(255,240,240,240)
#Taille de la fenêtre.
$largeurA = $formA.width
$hauteurA = $formA.height
#DataGrid - Options générales.
#SelectionMode -> CellSelect, FullRowSelect, FullColumnSelect,
#SelectionMode -> RowHeaderSelect, ColumnHeaderSelect.
#ScrollBars ----> None, Horizontal, Vertical, Both.
$gridA1 = New-Object System.Windows.Forms.DataGridView
$gridA1.Location = New-Object Drawing.Point -1,-1
$gridA1.Size = New-Object Drawing.Point ($largeurA-14),($hauteurA-72)
$gridA1.ScrollBars = "Vertical"
$gridA1.ReadOnly = $false
$gridA1.AutoSize = $false
$gridA1.GridColor = "Black"
$gridA1.AllowUserToResizeRows = $true
$gridA1.BorderStyle = [System.Windows.Forms.BorderStyle]::None
$gridA1.BackgroundColor = [System.Drawing.Color]::FromArgb(255,240,240,240)
$gridA1.DefaultCellStyle.SelectionBackColor = [System.Drawing.Color]::FromArgb(255,94,191,212)
$gridA1.SelectionMode = "FullRowSelect"
$gridA1.MultiSelect = $false
#DataGrid - Style de l'entête.
#ColumnHeadersHeightSizeMode -> EnableResizing, DisableResizing, AutoSize.
#ColumnHeadersBorderStyle ----> Custom, Single, Raised, Sunken, None.
$gridA1.RowHeadersVisible = $false
$gridA1.ColumnHeadersVisible = $true
$gridA1.ColumnHeadersHeightSizeMode = "DisableResizing"
$gridA1.EnableHeadersVisualStyles = $false
$gridA1.ColumnHeadersDefaultCellStyle.BackColor = [System.Drawing.Color]::FromArgb(255,44,40,109)
$gridA1.ColumnHeadersDefaultCellStyle.ForeColor = "White"
$gridA1.ColumnHeadersDefaultCellStyle.Alignment = "MiddleCenter"
$gridA1.ColumnHeadersBorderStyle = "Single"
#DataGrid - Ajouter les colonnes.
[void]$gridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$gridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewTextBoxColumn))
[void]$gridA1.Columns.Add((New-Object System.Windows.Forms.DataGridViewComboBoxColumn))
#DataGrid - Ajouter le texte des entêtes de colonnes.
$gridA1.Columns[0].Name = "Titre"
$gridA1.Columns[1].Name = "Editeur"
$gridA1.Columns[2].Name = "Nb Volume"
#DataGrid - Données pour la ComboBox.
$gridA1.Columns[2].DataSource = @("1","2","3","4","5","6","7","8","9","10","11","12")
$gridA1.Columns[2].FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
#DataGrid - Options des colonnes.
#SortMode -> NotSortable, Automatic, Programmatic.
foreach($column in $gridA1.Columns)
{
$column.SortMode = "NotSortable"
$column.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::Fill
}
#DataGrid - Alignement.
#Alignment -> NotSet, TopLeft, TopCenter, TopRight, MiddleLeft, MiddleCenter,
#Alignment -> MiddleRight, BottomLeft, BottomCenter, BottomRight.
$gridA1.Columns[2].DefaultCellStyle.Alignment = "MiddleCenter"
#DataGrid - Taille de colonne.
#En mode "Fill", il faut laisser une colonnes sans taille fixe.
$gridA1.Columns[2].Width = 80
#DataGrid - Ajouter les lignes de données.
[void]$gridA1.Rows.Add("Jumbor" ,"Kana" ,"2" )
[void]$gridA1.Rows.Add("Battle Game" ,"Doki-Doki" ,"2" )
[void]$gridA1.Rows.Add("Re:Teen" ,"Doki-Doki" ,"3" )
[void]$gridA1.Rows.Add("Imotep" ,"Kioon" ,"10")
[void]$gridA1.Rows.Add("Pluto" ,"Kana" ,"8" )
#Bouton - Annuler.
$buttonA1 = New-Object Windows.Forms.Button
$buttonA1.Location = New-Object Drawing.Point ($largeurA-102),($hauteurA-67)
$buttonA1.Size = New-Object Drawing.Point 80,23
$buttonA1.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$buttonA1.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
$buttonA1.Text = "Quitter"
$buttonA1.Add_Click({ $formA.Close() })
#Bouton - Valider.
$buttonA2 = New-Object Windows.Forms.Button
$buttonA2.Location = New-Object Drawing.Point ($largeurA-187),($hauteurA-67)
$buttonA2.Size = New-Object Drawing.Point 80,23
$buttonA2.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$buttonA2.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
$buttonA2.Text = "OK"
$buttonA2.Add_Click({
#Index de la 1er cellule selectionné.
$r = $gridA1.SelectedCells[0].RowIndex
$c = $gridA1.SelectedCells[0].ColumnIndex
#Nombre de ligne de données.
$n = ($gridA1.RowCount - 1)
#Si la ligne sélectionné est valide.
if (($r -ne $n) -and (![string]::IsNullOrEmpty($r)))
{
#Afficher les données.
$titre = $gridA1.SelectedCells[0].Value
$editeur = $gridA1.SelectedCells[1].Value
$volume = $gridA1.SelectedCells[2].Value
Write-Host $titre "-" $editeur "-" $volume "volume(s)."
}
else
{
#Sinon afficher une erreur.
Write-Host "La valeur sélectionné n'est pas valide."
}
})
#Lier.
$formA.Controls.Add($gridA1)
$formA.Controls.Add($buttonA1)
$formA.Controls.Add($buttonA2)
#Events.
$formA.Add_Load({
$gridA1.ClearSelection()
$formA.Activate()
})
$formA.Add_Resize({
#Ajuste la position des contrôles lorsque la fenêtre change de taille.
$gridA1.Size = New-Object Drawing.Point ($formA.width-14) ,($formA.height-72)
$buttonA1.Location = New-Object Drawing.Point ($formA.width-102),($formA.height-67)
$buttonA2.Location = New-Object Drawing.Point ($formA.width-187),($formA.height-67)
})
#Afficher.
[void]$formA.ShowDialog()
vendredi 19 octobre 2018
Réaliser une image ronde.
Je vais revenir un peu sur les graphismes dans cet article. Nous allons voir comment créer une image d'avatar tout ronde avec PowerShell. Dans l'exemple suivant, je crée une fenêtre transparente dans laquelle j'affiche une image toute ronde à partir d'un fichier contenant une image classique. Pour des raisons pratiques, j'ai ajouté une fonction "Escape" pour pouvoir sortir facilement du programme.
#Assembly.
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
[void][reflection.assembly]::LoadWithPartialName("System.Drawing")
#Defini le chemin courant.
$curpath = ""
if ($psISE) { $curpath = Split-Path -parent $psISE.CurrentFile.Fullpath }
else { $curpath = Split-Path $MyInvocation.MyCommand.Path }
#Ouvre une fenêtre transparente sans bord ni fond.
$formA = New-Object Windows.Forms.Form
$formA.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$formA.Size = New-Object System.Drawing.Size(100,100)
$formA.FormBorderStyle = "None"
$formA.TopMost = 1
$formA.BackColor = [System.Drawing.Color]::FromArgb(255,1,2,3)
$formA.TransparencyKey = [System.Drawing.Color]::FromArgb(255,1,2,3)
#Crée un contrôle image.
$imageA1 = New-Object System.Windows.Forms.pictureBox
$imageA1.Location = New-Object Drawing.Point 0,0
$imageA1.Size = New-Object System.Drawing.Size(60,60)
#Charge le fichier image à traiter.
#Il doit être au même endroit que le script.
#Notre fichier contient une image classique rectangulaire.
Try { $file = New-Object System.Drawing.Bitmap($curpath+"\av.png") }
Catch { Exit }
#Créer un Bitmap.
#Correspond ici à une feuille vierge (transparente).
$cgdata = New-Object System.Drawing.Bitmap(60,60)
#Créer un objet Graphics.
#Cet objet nous permettra de dessiner sur notre feuille.
$graphic = [System.Drawing.Graphics]::FromImage($cgdata)
#Nous allons redimensionné l'image.
#Pour obtenir une meilleur qualité, nous allons utiliser l'option suivante.
$graphic.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
#Nous allons maintenant définir une zone de dessin sur notre feuille.
#Ici, ma zone est un cercle de 60px sur 60px. Une fois appliqué, seule
#la zones définit sera dessinable. Rien ne sera modifié en dehors de la zone.
$grpath = New-Object System.Drawing.Drawing2D.GraphicsPath(0)
$grpath.AddEllipse(0, 0, 60, 60)
$graphic.SetClip($grpath)
#Copie l'image ac.png dans la zone dessinable sur la feuille.
#J'utilise ici DrawImage pour forcer le redimensionnement
#de l'image à la taille de ma feuille.
$graphic.DrawImage($file, 0, 0, 60, 60)
#Puis j'applique le dessin obtenu au contrôle image.
$imageA1.Image = $cgdata
$graphic.Dispose()
#Fermer la fenêtre lorsque l'on appuie sur la touche "Escape".
$formA.add_KeyDown({ If ($_.KeyCode -eq "Escape") { $formA.Close() } })
#Attache les contrôles à la fenêtre.
$formA.controls.add($labelA1)
$formA.controls.add($imageA1)
#Affiche le tout.
[void]$formA.ShowDialog()
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
[void][reflection.assembly]::LoadWithPartialName("System.Drawing")
#Defini le chemin courant.
$curpath = ""
if ($psISE) { $curpath = Split-Path -parent $psISE.CurrentFile.Fullpath }
else { $curpath = Split-Path $MyInvocation.MyCommand.Path }
#Ouvre une fenêtre transparente sans bord ni fond.
$formA = New-Object Windows.Forms.Form
$formA.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$formA.Size = New-Object System.Drawing.Size(100,100)
$formA.FormBorderStyle = "None"
$formA.TopMost = 1
$formA.BackColor = [System.Drawing.Color]::FromArgb(255,1,2,3)
$formA.TransparencyKey = [System.Drawing.Color]::FromArgb(255,1,2,3)
#Crée un contrôle image.
$imageA1 = New-Object System.Windows.Forms.pictureBox
$imageA1.Location = New-Object Drawing.Point 0,0
$imageA1.Size = New-Object System.Drawing.Size(60,60)
#Charge le fichier image à traiter.
#Il doit être au même endroit que le script.
#Notre fichier contient une image classique rectangulaire.
Try { $file = New-Object System.Drawing.Bitmap($curpath+"\av.png") }
Catch { Exit }
#Créer un Bitmap.
#Correspond ici à une feuille vierge (transparente).
$cgdata = New-Object System.Drawing.Bitmap(60,60)
#Créer un objet Graphics.
#Cet objet nous permettra de dessiner sur notre feuille.
$graphic = [System.Drawing.Graphics]::FromImage($cgdata)
#Nous allons redimensionné l'image.
#Pour obtenir une meilleur qualité, nous allons utiliser l'option suivante.
$graphic.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
#Nous allons maintenant définir une zone de dessin sur notre feuille.
#Ici, ma zone est un cercle de 60px sur 60px. Une fois appliqué, seule
#la zones définit sera dessinable. Rien ne sera modifié en dehors de la zone.
$grpath = New-Object System.Drawing.Drawing2D.GraphicsPath(0)
$grpath.AddEllipse(0, 0, 60, 60)
$graphic.SetClip($grpath)
#Copie l'image ac.png dans la zone dessinable sur la feuille.
#J'utilise ici DrawImage pour forcer le redimensionnement
#de l'image à la taille de ma feuille.
$graphic.DrawImage($file, 0, 0, 60, 60)
#Puis j'applique le dessin obtenu au contrôle image.
$imageA1.Image = $cgdata
$graphic.Dispose()
#Fermer la fenêtre lorsque l'on appuie sur la touche "Escape".
$formA.add_KeyDown({ If ($_.KeyCode -eq "Escape") { $formA.Close() } })
#Attache les contrôles à la fenêtre.
$formA.controls.add($labelA1)
$formA.controls.add($imageA1)
#Affiche le tout.
[void]$formA.ShowDialog()
Libellés :
Graphics,
GraphicsPath,
PowerShell,
Sekki
Blog édition :
06 Avril 2023
mardi 15 mai 2018
Dism - Install roles and features
DISM (Deployment Image Servicing and Management) est un outil en ligne de commande permettant de modifier l'image Windows. Dans cet article, nous allons voir comment activer et désactiver des rôles et des fonctionnalités Windows en ligne de commande avec la commande DISM.
Installer un rôle ou une fonctionnalité
Installation simple sur l'OS en cours :
DISM /Online /Enable-Feature /All /FeatureName:TFTP
Installation en spécifiant la source :
DISM /Online /Enable-Feature /FeatureName:TFTP /Source:Z:\sources\SxS /LimitAccess
/Online : Indique que l'opération se déroule sur un Système en cours d’exécution.
/Enable-Feature : Installe le rôle ou la fonctionnalité indiqué avec /FeatureName.
/FeatureName : Nom du rôle ou de la fonctionnalité.
/LimitAccess : Empêche Dism d'utiliser Windows Update comme source.
/Source : Indique le chemin de la source à utiliser pour l'installation.
/All : Indique qu'il faut installer toutes les dépendances et les fonctionnalités liées.
Désinstaller un rôle ou une fonctionnalité
Désinstallation simple sur l'OS en cours :
DISM /Online /Disable-Feature /FeatureName:TFTP
/Online : Indique que l'opération se déroule sur un Système en cours d’exécution.
/Disable-Feature : Désinstalle le rôle ou la fonctionnalité indiqué avec /FeatureName.
/FeatureName : Nom du rôle ou de la fonctionnalité.
Lister tout les rôles et fonctionnalités disponible
Liste simple sur l'OS en cours :
Dism /Online /Get-Features
/Online : Indique que l'opération se déroule sur un Système en cours d’exécution.
/Get-Feature : Liste les rôles et les fonctionnalités, et affiche si ils sont activé ou non.
Liste des noms à utiliser avec FeatureName
Get-WindowsFeature
Rôle (FeatureName) | Nom affiché |
RemoteAccess NetworkController ServerEssentialsRole Hyper-V MultiPointServerRole Fax DHCP DNS Web-Server Web-WebServer Web-Static-Content Web-Default-Doc Web-Http-Errors Web-Dir-Browsing Web-Http-Redirect Web-Http-Logging Web-Request-Monitor Web-Log-Libraries Web-Http-Tracing Web-Stat-Compression Web-Dyn-Compression Web-Filtering Web-Basic-Auth Web-Digest-Auth Web-Client-Auth Web-Windows-Auth Web-CertProvider Web-Asp-Net45 Web-CGI Web-Net-Ext45 Web-ISAPI-Ext Web-ISAPI-Filter Web-Mgmt-Console Web-Metabase Web-Scripting-Tools Web-Ftp-Service HostGuardianServiceRole AD-Domain-Services ADLDS ADRMS Remote-Desktop-Services VolumeActivation Print-Services AD-Certificate WDS ADFS-Federation FS-FileServer FS-Data-Deduplication Storage-Services NPAS UpdateServices ... |
Accès à distance Contrôleur de réseau Expérience Windows Server Essentials Hyper-V MultiPoint Services Serveur de télécopie Serveur DHCP Serveur DNS Serveur Web (IIS) Serveur Web Contenu statique Document par défaut Erreurs HTTP Exploration de répertoire Redirection HTTP Journalisation HTTP Observateur de demandes Outils de journalisation Suivi de traces Compression du contenu statique Compression de contenu dynamique Filtrage des demandes Authentification de base Authentification Digest Authentification par mappage de certificat Authentification Windows Prise en charge centralisée des certificat ASP.NET 4.6 CGI Extensibilité .NET 4.6 Extensions ISAPI Filtres ISAPI Console de gestion IIS Compatibilité de métadonnées IIS 6 Scripts et outils de gestion IIS Service FTP Service Guardian hôte Services AD DS Services AD LDS Services AD RMS Services Bureau à distance Services d’activation en volume Services d’impression et de numérisation Services de certificats Active Directory Services de déploiement Windows Services de fédération Active Directory Serveur de fichiers Déduplication des données Services de stockage Services de stratégie et d’accès réseau Services WSUS ... |
Libellés :
DISM,
PowerShell,
Sekki
Blog édition :
06 Avril 2023
Pays/territoire :
France
vendredi 23 mars 2018
Annonce - Eco7 v1.4.0
Avec Eco7 version 1.4.0, j'ai pratiquement réécris l'ensemble de l'application. Si le concept reste inchangé, il n'y a pas une seul fonction qui n'a pas du être remanié ou optimisé. C'est un gros travail qui m'a longtemps refroidi. Mais j'ai finalement sauté le pas ^^.
Les principales modifications sont l’intégration de Lite-DB dans Eco7 pour stocker les données et les journaux. L'apport de la base de données permet de travailler directement sur la base de données au lieu de charger un fichier en mémoire et de sauvegarder à la fermeture du programme. Cela apporte plus de fiabilité mais aussi plus de rapidité dans le traitement des informations.
J'ai ajouté une nouvelle fonctionnalités afin d'afficher un rapport de surveillance pour chaque icône. Ceci permet d'avoir un tableau plus simple à lire et avec des alarmes plus détaillé.
J'ai ajouté la possibilité de surveiller de décalage des horloges des serveurs Windows par rapport à un serveur NTP de référence lorsque l'option Wmi est activé. Actuellement, j'utilise les seuils suivant : Inférieur à 1s = vert, de 1-5s = jaune, 5-60s = orange, plus de 60s = rouge.
N'hésitez pas à vous rendre sur la page d'Eco7 pour avoir plus d'information.
Spoiler : Pour la prochaine version, je travaille sur l'intégration de SharpSnmpLib dans Eco7.
Libellés :
Eco7,
Monitoring,
PowerShell,
Sekki,
Surveillance
Blog édition :
06 Avril 2023
Pays/territoire :
France
mercredi 21 mars 2018
Powershell et SNMP
Pour récupérer des informations SNMP avec Windows Powershell, j'utilise dans cet article SharpSnmpLib.dll. L'exemple proposé ici montre en particulier comment utiliser les commandes SnmpWalker et SnmpGet avec Windows Powershell.
Le SNMP est un protocole client serveur utilisé pour transmettre l'état des services et applications d'un serveurs vers une console de surveillance. Le protocole SNMP se divise en deux principes de communication. Le mode Pull à l'initiative du client et le mode Push, à l'initiative du serveur. Dans le mode Pull le client va lire les informations mis à disposition par le serveur (snmpwalk, snmpget). Dans le mode Push, le client va écouté les informations envoyé par le serveur (snmptrap, snmptrapd).
J'ai testé un article très intéressant sur la façon de récupérer des informations SNMP en PowerShell. Si vous maitrisez un minimum l'anglais, je vous invite à le lire l'article en référence. Vous trouverez le lien du site ci-dessous. Par contre j'ai eu un peu de mal à récupérer le fichier "SharpSnmpLib.dll". Je vais donc ajouter un lien avec la source. L'exemple que je vous propose aujourd'hui est une donc une version légèrement remanier en français.
Principe général du protocole SNMP
Le SNMP est un protocole client serveur utilisé pour transmettre l'état des services et applications d'un serveurs vers une console de surveillance. Le protocole SNMP se divise en deux principes de communication. Le mode Pull à l'initiative du client et le mode Push, à l'initiative du serveur. Dans le mode Pull le client va lire les informations mis à disposition par le serveur (snmpwalk, snmpget). Dans le mode Push, le client va écouté les informations envoyé par le serveur (snmptrap, snmptrapd).
Référence
J'ai testé un article très intéressant sur la façon de récupérer des informations SNMP en PowerShell. Si vous maitrisez un minimum l'anglais, je vous invite à le lire l'article en référence. Vous trouverez le lien du site ci-dessous. Par contre j'ai eu un peu de mal à récupérer le fichier "SharpSnmpLib.dll". Je vais donc ajouter un lien avec la source. L'exemple que je vous propose aujourd'hui est une donc une version légèrement remanier en français.
Site de référence : https://vwiki.co.uk/SNMP_and_PowerShell
Télécharger la Dll : SharpSnmpLib.dll
Exemple
Dans cet exemple j'utilise le mode SNMP Pull pour lire les information mis à disposition sur un système distant. Pour cet exemple, il faut créer un dossier "lib" au même niveau que le script, et y décompresser l'archive téléchargée ci-dessus.
############################################################
# Snmp : SharpSnmpLib v7.6
# Powershell : Version 2.0
############################################################
#Chemin courant.
$curpath = ""
if ($psISE) { $curpath = split-path -parent $psISE.CurrentFile.Fullpath }
else { $curpath = Split-Path $MyInvocation.MyCommand.Path }
#Chargement des librairies.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
Try { [void][Reflection.Assembly]::LoadFile($curpath+"\lib\SharpSnmpLib.dll") }
Catch { write-host "SharpSnmpLib.dll manquant.";Return }
############################################################
# Fonctions SNMP
############################################################
#Fonction - Créer un type générique.
function Snmp-GenericObject ([string]$typeName,[string[]]$typeParams,[object[]]$constructorParams)
{
#Créer le nom du type générique.
$genericTypeName = $typeName + "``" + $typeParams.Count
$genericType = [Type] $genericTypeName
if (!$genericType) { throw "Impossible de trouver le type générique $genericTypeName" }
#Lier les parametres de type à celui-ci.
[type[]] $typedParams = $typeParams
$closedType = $genericType.MakeGenericType($typedParams)
if (!$closedType) { throw "Impossible de finaliser le type $genericType" }
#Créer la version final du type générique.
,[Activator]::CreateInstance($closedType, $constructorParams)
}
#Fonction - SnmpWalker.
function Snmp-Walker ([string]$sIP, $sOIDstart, [string]$Community = "public", [int]$UDPport = 161, [int]$TimeOut=3000)
{
#$TimeOut est en msec, 0 ou -1 pour infini.
#Créer un objet OID.
$oid = New-Object Lextm.SharpSnmpLib.ObjectIdentifier ($sOIDstart)
#Créer la liste pour les résultats (compatible powershell v2).
$results = Snmp-GenericObject System.Collections.Generic.List Lextm.SharpSnmpLib.Variable
#Créer un point de terminaison pour le serveur SNMP.
$ip = [System.Net.IPAddress]::Parse($sIP)
$svr = New-Object System.Net.IpEndPoint ($ip, 161)
#Utiliser SNMP v2 avec le mode "WithinSubTree".
$ver = [Lextm.SharpSnmpLib.VersionCode]::V2
$walkMode = [Lextm.SharpSnmpLib.Messaging.WalkMode]::WithinSubtree
#Lancer le requête SNMP.
Try { $null = [Lextm.SharpSnmpLib.Messaging.Messenger]::Walk($ver, $svr, $Community, $oid, $results, $TimeOut, $walkMode) }
Catch { Write-Host "Erreur SNMP : $_"; Return }
#Dans cet exemple j'ai changé le format de sortie pour un tableau d'objet.
$rtn = @()
foreach ($var in $results)
{
$obj = New-Object System.Object
$obj | Add-Member -type NoteProperty -name OID -Value ([string]$var.Id)
$obj | Add-Member -type NoteProperty -name Data -Value ([string]$var.Data)
$rtn += $obj
}
#Résultats.
$rtn
}
#Fonction - GetSnmp.
function Snmp-Get ([string]$sIP, $sOIDs, [string]$Community = "public", [int]$UDPport = 161, [int]$TimeOut=3000)
{
#$TimeOut est en msec, 0 ou -1 pour infini.
#Créer une liste de variables OID (compatible powershell v2).
$vList = Snmp-GenericObject System.Collections.Generic.List Lextm.SharpSnmpLib.Variable
foreach ($sOID in $sOIDs)
{
$oid = New-Object Lextm.SharpSnmpLib.ObjectIdentifier ($sOID)
$vList.Add($oid)
}
#Créer un point de terminaison pour le serveur SNMP.
$ip = [System.Net.IPAddress]::Parse($sIP)
$svr = New-Object System.Net.IpEndPoint ($ip, 161)
#Utiliser SNMP v2.<
$ver = [Lextm.SharpSnmpLib.VersionCode]::V2
#Lancer le requête SNMP.
Try { $msg = [Lextm.SharpSnmpLib.Messaging.Messenger]::Get($ver, $svr, $Community, $vList, $TimeOut) }
Catch { Write-Host "SNMP Get error: $_"; Return }
#Dans cet exemple j'ai changé le format de sortie pour un tableau d'objet.
$rtn = @()
foreach ($var in $msg)
{
$obj = New-Object System.Object
$obj | Add-Member -type NoteProperty -name OID -Value ([string]$var.Id)
$obj | Add-Member -type NoteProperty -name Data -Value ([string]$var.Data)
$rtn += $obj
}
#Résultats.
$rtn
}
############################################################
# Zone de test.
#
# Usage :
# Snmp-Walker IP OIDSTART [Community] [Port] [Timeout]
# Snmp-Get IP OID [Community] [Port] [Timeout]
############################################################
#Snmp Walker.
#Remplacer l'adresse ip par une adresse valide.
Snmp-Walker "127.0.0.1" ".1.3.6.1.2.1" | Out-String
Snmp-Walker "127.0.0.1" ".1.3.6.1.2.1" | Out-GridView
#Snmp Get.
#Remplacer l'adresse ip par une adresse valide.
Snmp-Get "127.0.0.1" ".1.3.6.1.2.1.1.5.0" | Out-String
Snmp-Get "127.0.0.1" ".1.3.6.1.2.1.1.5.0" | Out-GridView
#Fin.
# Snmp : SharpSnmpLib v7.6
# Powershell : Version 2.0
############################################################
#Chemin courant.
$curpath = ""
if ($psISE) { $curpath = split-path -parent $psISE.CurrentFile.Fullpath }
else { $curpath = Split-Path $MyInvocation.MyCommand.Path }
#Chargement des librairies.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
Try { [void][Reflection.Assembly]::LoadFile($curpath+"\lib\SharpSnmpLib.dll") }
Catch { write-host "SharpSnmpLib.dll manquant.";Return }
############################################################
# Fonctions SNMP
############################################################
#Fonction - Créer un type générique.
function Snmp-GenericObject ([string]$typeName,[string[]]$typeParams,[object[]]$constructorParams)
{
#Créer le nom du type générique.
$genericTypeName = $typeName + "``" + $typeParams.Count
$genericType = [Type] $genericTypeName
if (!$genericType) { throw "Impossible de trouver le type générique $genericTypeName" }
#Lier les parametres de type à celui-ci.
[type[]] $typedParams = $typeParams
$closedType = $genericType.MakeGenericType($typedParams)
if (!$closedType) { throw "Impossible de finaliser le type $genericType" }
#Créer la version final du type générique.
,[Activator]::CreateInstance($closedType, $constructorParams)
}
#Fonction - SnmpWalker.
function Snmp-Walker ([string]$sIP, $sOIDstart, [string]$Community = "public", [int]$UDPport = 161, [int]$TimeOut=3000)
{
#$TimeOut est en msec, 0 ou -1 pour infini.
#Créer un objet OID.
$oid = New-Object Lextm.SharpSnmpLib.ObjectIdentifier ($sOIDstart)
#Créer la liste pour les résultats (compatible powershell v2).
$results = Snmp-GenericObject System.Collections.Generic.List Lextm.SharpSnmpLib.Variable
#Créer un point de terminaison pour le serveur SNMP.
$ip = [System.Net.IPAddress]::Parse($sIP)
$svr = New-Object System.Net.IpEndPoint ($ip, 161)
#Utiliser SNMP v2 avec le mode "WithinSubTree".
$ver = [Lextm.SharpSnmpLib.VersionCode]::V2
$walkMode = [Lextm.SharpSnmpLib.Messaging.WalkMode]::WithinSubtree
#Lancer le requête SNMP.
Try { $null = [Lextm.SharpSnmpLib.Messaging.Messenger]::Walk($ver, $svr, $Community, $oid, $results, $TimeOut, $walkMode) }
Catch { Write-Host "Erreur SNMP : $_"; Return }
#Dans cet exemple j'ai changé le format de sortie pour un tableau d'objet.
$rtn = @()
foreach ($var in $results)
{
$obj = New-Object System.Object
$obj | Add-Member -type NoteProperty -name OID -Value ([string]$var.Id)
$obj | Add-Member -type NoteProperty -name Data -Value ([string]$var.Data)
$rtn += $obj
}
#Résultats.
$rtn
}
#Fonction - GetSnmp.
function Snmp-Get ([string]$sIP, $sOIDs, [string]$Community = "public", [int]$UDPport = 161, [int]$TimeOut=3000)
{
#$TimeOut est en msec, 0 ou -1 pour infini.
#Créer une liste de variables OID (compatible powershell v2).
$vList = Snmp-GenericObject System.Collections.Generic.List Lextm.SharpSnmpLib.Variable
foreach ($sOID in $sOIDs)
{
$oid = New-Object Lextm.SharpSnmpLib.ObjectIdentifier ($sOID)
$vList.Add($oid)
}
#Créer un point de terminaison pour le serveur SNMP.
$ip = [System.Net.IPAddress]::Parse($sIP)
$svr = New-Object System.Net.IpEndPoint ($ip, 161)
#Utiliser SNMP v2.<
$ver = [Lextm.SharpSnmpLib.VersionCode]::V2
#Lancer le requête SNMP.
Try { $msg = [Lextm.SharpSnmpLib.Messaging.Messenger]::Get($ver, $svr, $Community, $vList, $TimeOut) }
Catch { Write-Host "SNMP Get error: $_"; Return }
#Dans cet exemple j'ai changé le format de sortie pour un tableau d'objet.
$rtn = @()
foreach ($var in $msg)
{
$obj = New-Object System.Object
$obj | Add-Member -type NoteProperty -name OID -Value ([string]$var.Id)
$obj | Add-Member -type NoteProperty -name Data -Value ([string]$var.Data)
$rtn += $obj
}
#Résultats.
$rtn
}
############################################################
# Zone de test.
#
# Usage :
# Snmp-Walker IP OIDSTART [Community] [Port] [Timeout]
# Snmp-Get IP OID [Community] [Port] [Timeout]
############################################################
#Snmp Walker.
#Remplacer l'adresse ip par une adresse valide.
Snmp-Walker "127.0.0.1" ".1.3.6.1.2.1" | Out-String
Snmp-Walker "127.0.0.1" ".1.3.6.1.2.1" | Out-GridView
#Snmp Get.
#Remplacer l'adresse ip par une adresse valide.
Snmp-Get "127.0.0.1" ".1.3.6.1.2.1.1.5.0" | Out-String
Snmp-Get "127.0.0.1" ".1.3.6.1.2.1.1.5.0" | Out-GridView
#Fin.
Libellés :
PowerShell,
Sekki,
Snmp,
SnmpGet,
SnmpWalk,
SnmpWalker
Blog édition :
06 Avril 2023
Pays/territoire :
France
Inscription à :
Articles (Atom)