Avez vous déjà rencontré l'expérience de la console Powershell ISE qui fige lorsque vous utilisez Sharepoint Online et le MFA ?
Je sais c'est désagréable, surtout quand un script tourne depuis un moment, voici donc un petit contournement pour corriger ce problème.
- Créez sur votre bureau un raccourcis de Powershell ISE.
- Sélectionnez le, faites un clic droit et enfin sélectionnez "Propriétés".
- Dans le champs "Cible", ajoutez " -Mta" à la fin.
Maintenant lorsque vous exécuterez la console, lancez la via ce raccourcis et les problèmes de console qui fige seront un mauvais souvenir.
Le script suivant est une nouvelle version d'un script récemment proposé. Ont été rajouté le choix entre suppression et mode maintenance (on verifie aussi que la machine est déjà en mode maintenance)
DeleteOrMaintenanceAgentUponPropertyValue.ps1 (14,85 kb)
## DeleteOrMaintenanceAgentUponPropertyValue.ps1
## SCOM - REMOVE FROM CONSOLE OR PUT IN MAINTENANCE MODE, AGENT(S) THAT HAVE SPECIFIC VALUES IN ONE OR MORE CLASS PROPERTY.
## AUTHOR: C.JOURDAN
## Version: 1.1
## PARAMETERS
## $MS: Target Management Server
## $ObjectClass: Display Name of Target Class
## $FirstProperty: name of class property
## $FirstPropVal: multi value possible of $FirstProperty
## $Action: DELETE or MAINTENANCE
## $MaintenanceDuration: Nb of minutes for Maintenance Mode
## $ThreshNotDelete: Nb of found computers to delete over which we only warn (NO AUTOMATIC DELETE)
## NOTES: $ThreshNotDelete PARAMETER IS A SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
#PARAMETERS
Param(
[Parameter(Mandatory=$false)]
$MGroup,
[Parameter(Mandatory=$false)]
$MS="MyMS",
[Parameter(Mandatory=$false)]
$ObjectClass="MyClass",
[Parameter(Mandatory=$false)]
$FirstProperty='MyProperty',
[Parameter(Mandatory=$false)]
$FirstPropVal="^.*(AZERTY|QWERTY).*$",
<# -- ADDITIONAL PROPERTIES FROM $ObjectClass INSTANCE -- SEE CLASS INSTANCE RETRIEVE SECTION
[Parameter(Mandatory=$false)]
$SecondProperty='Prop2',
[Parameter(Mandatory=$false)]
$SecondPropVal='Value2'
#>
[Parameter(Mandatory=$false)]
$Action = "Maintenance",
[Parameter(Mandatory=$false)]
$MaintenanceDuration = 30,
[Parameter(Mandatory=$false)]
$ThreshNotDelete = 10
)
#ScriptName
$ScriptName = "DeleteOrMaintenanceAgentUponPropertyValue.ps1"
#FUNCTIONS
# NewEventSource
# Check of a source existance in the 'operation manager' eventlog that match the script name, to log some events.
Function NewEventSource
{
if(!(Test-Path "HKLM:\SYSTEM\CurrentControlSet\services\eventlog\Operations Manager\$ScriptName"))
{
New-EventLog -LogName "Operations Manager" -Source $ScriptName
}
}
# DeleteSCOMAgent
# Remove agent from SCOM Console.
Function DeleteSCOMAgent
{
Param(
[string[]]$AgentComputerName,
[string]$MSServer
)
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
function New-Collection ( [type] $type )
{
$typeAssemblyName = $type.AssemblyQualifiedName;
$collection = new-object "System.Collections.ObjectModel.Collection``1[[$typeAssemblyName]]";
return ,($collection);
}
# Connect to management group
Write-output "Connecting to management group "$ConnectionSetting.name""
$ConnectionSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MSServer)
$admin = $ConnectionSetting.GetAdministration()
Write-output "Getting agent managed computers"
$agentManagedComputers = $admin.GetAllAgentManagedComputers()
# Get list of agents to delete
foreach ($name in $AgentComputerName)
{
Write-output "Checking for $name"
foreach ($agent in $agentManagedComputers)
{
if ($deleteCollection -eq $null)
{
$deleteCollection = new-collection $agent.GetType()
}
if (@($agent.PrincipalName -eq $name))
{
Write-output "Matched $name"
$deleteCollection.Add($agent)
break
}
}
}
if ($deleteCollection.Count -gt 0)
{
Write-output "Deleting agents"
$admin.DeleteAgentManagedComputers($deleteCollection)
if($?){
$Script:result="Agents deleted"
Write-Output $result
}
Else {
$result="Error during deletion of one ore more agent"
Write-Output $result
}
}
Else
{
$result="No Agent found to delete"
Write-Output $result
}
}
Function SetMM
{
# Function SetMM
########################################################################
#
#
[CmdletBinding()]
param(
[string]$HostToMM,
[string]$Duration
)
$startTime = [DateTime]::Now
$endTime = $startTime.AddMinutes($Duration)
# Get "Microsoft.Windows.Computer" Class
$Class = get-SCOMclass | where-object {$_.Name -eq "Microsoft.Windows.Computer"};
$Instance = Get-SCOMClassInstance -Class $Class | Where-Object {$_.Displayname -like "$HostToMM*"};
Start-SCOMMaintenanceMode -Instance $Instance -Reason "PlannedOther" -EndTime $endTime -Comment "PLANNED BY SCOM AGENT REMOVER" -ErrorAction Stop
}
#END FUNCTIONS
#Log of script execution
NewEventSource
$message = "Execution du script $ScriptName"
$message
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 999 -Message $message -EntryType Information
# Check if $Action is valid
if ($Action -notmatch "^delete|maintenance$")
{
$message = "NO VALID ACTION HAS BEEN CHOOSED - POSSIBLE VALUE: `"DELETE`" OR `"MAINTENANCE`""
write-host -ForegroundColor Yellow $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1000 -Message $message -EntryType Warning
exit 1
}
#Import of SCOM Powershell module
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
$message = "ERROR DURING IMPORT OF SCOM PS MODULE"
write-host -ForegroundColor red $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1001 -Message $message -EntryType Error
exit 1
}
#Connection to management group $MGroup
try
{
New-SCOMManagementGroupConnection -ComputerName $MS
}
catch
{
$message = "ERROR DURING CONNECTION TO $MS"
write-host -ForegroundColor red $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1002 -Message $message -EntryType Error
exit 1
}
# Get $ObjectClass Class
$Class = Get-SCOMClass -displayname $ObjectClass | Where-Object {$_.PropertyCollection -match "^.*($FirstProperty|$SecondProperty).*$"} -ErrorAction stop ## -- WE CHECK THAT THE TARGET CLASS REALLY HOLD THE WANTED PROPERTIES
if (!($Class))
{
$message = "ERROR DURING RETRIEVE OF '$ObjectClass' CLASS. (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
write-host -ForegroundColor red $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1003 -Message $message -EntryType Error
exit 1
}
# Get Computers that have $FirstProperty value as: $FirstPropVal
try
{
$TargetComp = $Class | Get-SCOMClassInstance | Where-Object {
$_."[$($Class.Name)].$FirstProperty".value -match $FirstPropVal -OR $_.$FirstProperty -match $FirstPropVal` ##-- DIFFERENT COMBINATION (THE "[$($Class.Name)]" SYNTAX IS TO INCLUDE CASE OF A NOTE PROPERTY
#-AND $_."[$($Class.Name)].$SecondProperty".value -eq $SecondPropVal -OR $_.$SecondProperty -eq $SecondPropVal` ##-- ADDITIONAL POTENTIAL PROPERTIES (SEE SCRIPT PARAMS)
} -ErrorAction Stop
#$TargetComp = $Class | Get-SCOMClassInstance | Where-Object { ## -- TO TEST UNFOUND COMPUTER SCENARIO
#$_."[$($Class.Name)].$FirstProperty".value -eq "azerty" -OR $_.$FirstProperty -eq "azerty"` ## -- TO TEST UNFOUND COMPUTER SCENARIO
#} -ErrorAction Stop ## -- TO TEST UNFOUND COMPUTER SCENARIO
}
catch
{
$message = "ERROR DURING RETRIEVE OF CLASS INSTANCES (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
write-host -ForegroundColor red $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1004 -Message $message -EntryType Error
exit 1
}
switch($Action)
{
"Delete" {
# Analyse the content of $TargetComp
switch($TargetComp.Count)
{
{$_ -lt 1} {
$message = "NO AGENT TO REMOVE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
Write-Host -F Blue -B White $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1005 -Message $message -EntryType Information
}
{$_ -ge 1 -AND $_ -le $ThreshNotDelete} ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
{
$message = "FOLLOWING AGENTS WILL BE REMOVED:"
Write-Host -F Yellow $message
$TargetComp.displayname
DeleteSCOMAgent -AgentComputerName $TargetComp.displayname -MSServer $MS
#$result
switch($result)
{
"Agents deleted"
{
$message = "FOLLOWING AGENTS HAS BEEN REMOVED FROM SCOM CONSOLE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") :`n "
$message += $TargetComp | foreach {$_.DisplayName ;"`n"}
write-host $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1006 -Message $message -EntryType Information
}
"Error during deletion of one ore more agent"
{
$message = "ERROR DURING DELETION OF ONE OR MORE AGENT! MANUAL CHECK REQUIRED (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") "
write-host $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1007 -Message $message -EntryType Warning
}
"No Agent found to delete"
{
$message = "NO AGENT FOUND TO DELETE - MANUAL CHECK REQUIRED (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
write-host $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1008 -Message $message -EntryType Warning
}
}
}
{$_ -gt $ThreshNotDelete} {
$message = "WARNING: NUMBER OF AGENTS TO REMOVE IS GREATER THAN 10 ! MANUAL CHECK REQUIRED" ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
Write-Host -F red $message
$TargetComp.displayname
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1009 -Message $message -EntryType Warning
}
}
}
"Maintenance" {
#Clear-Variable message
If ($TargetComp.Count -ge 1)
{
foreach ($target in $TargetComp)
{
If (Get-SCOMMaintenanceMode -Instance $target)
{
#$message += "`n$target IS ALREADY IN MAINTENANCE MODE"
$AlreadyInMM += "$target`n"
}
Else
{
SetMM -HostToMM $target -Duration $MaintenanceDuration
$PutInMM += "$target`n"
}
}
$message = "`nFOLLOWING AGENTS HAS BEEN SET IN MAINTENANCE MODE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") :`n"
$message += $PutInMM
$message += "`n`nFOLLOWING AGENTS ARE ALREADY IN MAINTENANCE MODE (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`") :`n"
$message += $AlreadyInMM
write-host $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1010 -Message $message -EntryType Information
}
Else
{
$message = "NO AGENT TO PUT IN MAINTENANCE MODE HAS BEEN FOUND. (CRITERIAS: Class=`"$ObjectClass`" - Property=`"$FirstProperty`" - Value=`"$FirstPropVal`")"
write-host $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1011 -Message $message -EntryType Information
}
}
default {
$message = "No action has been choosed. Possible value: `"Delete`" (Delete Agent from console) or `"Maintenance`" (Put corresponding computer in Maintenance Mode)"
write-host -ForegroundColor red $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1012 -Message $message -EntryType Error
exit 1
}
}
Le script ci-dessous propose de comparer un extract des agents scom avec une liste de machine, pour un suivi de déploiement par exemple.
Compare_SCOMAgent_ComputerList.ps1 (1,67 kb)
### COMPARE SCOM AGENTS AND COMPUTER LIST IN TXT FILE
#Parameters
Param(
[Parameter(Mandatory=$false)]
$MS="MyMS.MyDomain",
[Parameter(Mandatory=$false)]
$Cred = $(Get-Credential "MyDomain\Me"),
[Parameter(Mandatory=$false)]
$FilePath = "C:\ServerList.txt "
)
#Import du module SCOM
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
write-host -ForegroundColor red "Erreur lors de l'import du module SCOM"
}
#Connection au management group $MGroup
New-SCOMManagementGroupConnection -ComputerName $MS -Credential $Cred
# Recuperation de la liste des agents (netbios name
$agents = Get-SCOMAgent | select computername -ExpandProperty computername
# Import du fichier $FilePath
try
{
$ComputerList = Get-Content -Path $FilePath
}
catch
{
write-host -ForegroundColor red "Error during import of `"$FilePath`""
}
# Machines dans Scom ET dans la liste
$Both = $(Compare-Object -ReferenceObject $agents -DifferenceObject $ComputerList -IncludeEqual -ExcludeDifferent).inputobject
# Machines uniquement dans SCOM
$InScom = $(Compare-Object -ReferenceObject $agents -DifferenceObject $ComputerList | Where-Object {$_.sideindicator -eq "<="}).inputobject
# Machines uniquement dans la liste
$InFile = $(Compare-Object -ReferenceObject $agents -DifferenceObject $ComputerList | Where-Object {$_.sideindicator -eq "=>"}).inputobject
write-host -B White -F Blue "`n $($both.Count) COMPUTERS THAT ARE IN SCOM AND IN FILE:"
$Both
write-host -B White -F Blue "`n $($InScom.Count) COMPUTERS THAT ARE ONLY IN SCOM:"
$InScom
write-host -B White -F Blue "`n $($InList.Count) COMPUTERS THAT ARE ONLY IN FILE:"
$InFile
Aujourd'hui lorsque l'on utilise Exchange Online et les boites aux lettre de salle, la configuration par défaut du calendrier de ces boites ne permet de voir que le statut de celle-ci soit "Libre ou Occupée" en revanche il n'est pas possible de voir qui a réservé la salle.
C'est parce que par défaut les droits sur le calendrier sont en "AvailabilityOnly", comme le montre la capture ci dessous.
A l'aide de Powershell, il est possible de modifier les droits sur le calendrier pour afficher qui est la personne ayant fait la réservation, pour ce faire voici les cmdlets.
#Construction de la session Exchange Online
$cred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $Cred -Authentication Basic -AllowRedirection
# Import de la session
Import-PSSession $Session
# Audit des droits
Get-MailboxFolderPermission -Identity Nom_de_la_Salle_de_réunion:\calendar
# Modification des droits
Set-MailboxFolderPermission -Identity Nom_de_la_Salle_de_réunion:\calendar -User default -AccessRights LimitedDetails
Maintenant il est possible de voir le statut de la salle de réunion ainsi que les personnes l'ayant réservé.
Le script ci-dessous , permet de modifier le chemin cible d'un raccourcis
Etape 1 : Création d'une variable $nom_intranet
La variable "$nom_intranet" contenu dans le paramètre ci-dessous, corresponds au nom du répertoire où se trouve notre fichier ou dossier en "LNK".
Param (
[parameter(Mandatory=$true)][String]$nom_intranet
)
Etape 2 : Déclaration des variables
L'applet de commande Read-Host permet de lire une ligne d'entrée à partir de la console
[string]$ancien_cible = Read-Host "Saisir la valeur a remplacer EX:{\\SRV01} "
[string]$nouveau_cible = Read-Host "Saisir la nouvelle valeur EX:{\\SRV02} "
Etape 2 : Tratement du script
$raccourcis = Get-ChildItem -Recurse "\\SRV02\intranet\raccourci" -Include *.lnk
$obj = New-Object -ComObject WScript.Shell
ForEach($raccourci in $raccourcis){
$link = $obj.CreateShortcut($raccourci)
[string]$link.TargetPath = $link.TargetPath.Replace([String]$ancien_cible,[String]$nouveau_cible)
[string]$link.Save()
Write-Host $link.TargetPath -ForegroundColor green
}
Le script ci-dessous propose le scenario ou l'on doit automatiser la suppression d'un agent de la console (pas une desinstallation) en fonction de la valeur d'une ou plusieurs propriétés de l'instance d'une classe pour ce/ces agents.
Ceci peut permettre par exemple dans la cas de la présence d'une classe étendue (avec vos propres propriétés issues par exemple d'un outil tiers) de decommissionner un ou plusieurs agents automatiquement, selon la valeur de ces propriétés (Dans l'exemple inscrit par defaut dans les paramètres, on cherche la valeur 'Useless' ou 'Deprecated' de la propriété 'Usage' de la classe 'MyClass')
RemoveAgentUponPropertyVal.ps1 (10,67 kb)
## RemoveAgentUponPropertyVal.ps1
## SCOM - REMOVE AGENT(S) FROM CONSOLE THAT HAVE SPECIFIC VALUES IN ONE OR MORE CLASS PROPERTY.
## AUTHOR: C.JOURDAN
## Version: 1.0
## PARAMETERS
## $MS: Target Management Server
## $ObjectClass: Display Name of Target Class
## $FirstProperty: name of class property
## $FirstPropVal: multi value possible of $FirstProperty
## $ThreshNotDelete: Nb of found computers to delete over which we only warn (NO AUTOMATIC DELETE)
## NOTES: $ThreshNotDelete PARAMETER IS A SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
#PARAMETERS
Param(
[Parameter(Mandatory=$false)]
$MGroup,
[Parameter(Mandatory=$false)]
$MS='localhost',
[Parameter(Mandatory=$false)]
$ObjectClass = 'MyClass',
[Parameter(Mandatory=$false)]
$FirstProperty='Usage',
[Parameter(Mandatory=$false)]
$FirstPropVal="^.*(Useless|Deprecated).*$",
<# -- ADDITIONAL PROPERTIES FROM $ObjectClass INSTANCE -- SEE CLASS INSTANCE RETRIEVE SECTION
[Parameter(Mandatory=$false)]
$SecondProperty='Prop2',
[Parameter(Mandatory=$false)]
$SecondPropVal='Value2'
#>
[Parameter(Mandatory=$false)]
$ThreshNotDelete = 10
)
#ScriptName
$ScriptName = "RemoveAgentUponPropertyVal.ps1"
#FUNCTIONS
# NewEventSource
# Check of a source existance in the 'operation manager' eventlog that match the script name, to log some events.
Function NewEventSource
{
if(!(Test-Path "HKLM:\SYSTEM\CurrentControlSet\services\eventlog\Operations Manager\$ScriptName"))
{
New-EventLog -LogName "Operations Manager" -Source $ScriptName
}
}
# DeleteSCOMAgent
# Remove agent from SCOM Console.
Function DeleteSCOMAgent
{
Param(
[string[]]$AgentComputerName,
[string]$MSServer
)
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
function New-Collection ( [type] $type )
{
$typeAssemblyName = $type.AssemblyQualifiedName;
$collection = new-object "System.Collections.ObjectModel.Collection``1[[$typeAssemblyName]]";
return ,($collection);
}
# Connect to management group
Write-output "Connecting to management group"
$ConnectionSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MSServer)
$admin = $ConnectionSetting.GetAdministration()
Write-output "Getting agent managed computers"
$agentManagedComputers = $admin.GetAllAgentManagedComputers()
# Get list of agents to delete
foreach ($name in $AgentComputerName)
{
Write-output "Checking for $name"
foreach ($agent in $agentManagedComputers)
{
if ($deleteCollection -eq $null)
{
$deleteCollection = new-collection $agent.GetType()
}
if (@($agent.PrincipalName -eq $name))
{
Write-output "Matched $name"
$deleteCollection.Add($agent)
break
}
}
}
if ($deleteCollection.Count -gt 0)
{
Write-output "Deleting agents"
$admin.DeleteAgentManagedComputers($deleteCollection)
if($?){
$Script:result="Agents deleted"
Write-Output $result
}
Else {
$result="Error during deletion of one ore more agent"
Write-Output $result
}
}
Else
{
$result="No Agent found to delete"
Write-Output $result
}
}
#END FUNCTIONS
#Log of script execution
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1000 -Message "Execution du script $ScriptName" -EntryType Information
#Import of SCOM Powershell module
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
write-host -ForegroundColor red "Error during import of SCOM PS Module"
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1001 -Message "Error during import of SCOM PS Module" -EntryType Error
exit 1
}
#Connection to management group $MGroup
try
{
New-SCOMManagementGroupConnection -ComputerName $MS
}
catch
{
write-host -ForegroundColor red "Error during connection to MS $MS"
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1002 -Message "Error during connection to MS $MS" -EntryType Error
exit 1
}
# Get $ObjectClass Class
$Class = Get-SCOMClass -displayname $ObjectClass | Where-Object {$_.PropertyCollection -match "^.*($FirstProperty|$SecondProperty).*$"} -ErrorAction stop ## -- WE CHECK THAT THE TARGET CLASS REALLY HOLD THE WANTED PROPERTIES
if (!($Class))
{
$message = "ERROR DURING RETRIEVE OF '$ObjectClass' CLASS. CHECK THAT CLASS EXIST OR THAT THE PROPERTIES YOU WANT EXIST IN THIS CLASS"
write-host -ForegroundColor red $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1003 -Message $message -EntryType Error
exit 1
}
# Get Computers that have $FirstProperty value as: $FirstPropVal
try
{
$TargetComp = $Class | Get-SCOMClassInstance | Where-Object {
$_."[$($Class.Name)].$FirstProperty".value -match $FirstPropVal -OR $_.$FirstProperty -match $FirstPropVal` ##-- DIFFERENT COMBINATION (THE "[$($Class.Name)]" SYNTAX IS TO INCLUDE CASE OF A NOTE PROPERTY
#-AND $_."[$($Class.Name)].$SecondProperty".value -eq $SecondPropVal -OR $_.$SecondProperty -eq $SecondPropVal` ##-- ADDITIONAL POTENTIAL PROPERTIES (SEE SCRIPT PARAMS)
} -ErrorAction Stop
#$TargetComp = $Class | Get-SCOMClassInstance | Where-Object { ## -- TO TEST UNFOUND COMPUTER SCENARIO
#$_."[$($Class.Name)].$FirstProperty".value -eq "azerty" -OR $_.$FirstProperty -eq "azerty"` ## -- TO TEST UNFOUND COMPUTER SCENARIO
#} -ErrorAction Stop ## -- TO TEST UNFOUND COMPUTER SCENARIO
}
catch
{
$message = "Error during retrieve of '$ObjectClass' instances that have $FirstProperty : $FirstPropVal"
write-host -ForegroundColor red $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1004 -Message $message -EntryType Error
exit 1
}
# Analyse the content of $TargetComp
switch($TargetComp.Count)
{
{$_ -lt 1} {
$message = "NO AGENT TO REMOVE"
Write-Host -F Blue -B White $message
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1005 -Message $message -EntryType Information
}
{$_ -ge 1 -AND $_ -le $ThreshNotDelete} ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
{
$message = "FOLLOWING AGENTS WILL BE REMOVED:"
Write-Host -F Yellow $message
$TargetComp.displayname
DeleteSCOMAgent -AgentComputerName $TargetComp.displayname -MSServer $MS
#$result
switch($result)
{
"Agents deleted"
{
$message = "FOLLOWING AGENTS HAS BEEN REMOVED FROM SCOM CONSOLE SINCE THEIR $FirstProperty IS EQUAL: $FirstPropVal . $($TargetComp.displayname)"
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1006 -Message $message -EntryType Information
}
"Error during deletion of one ore more agent"
{
$message = "ERROR DURING DELETION OF ONE OR MORE AGENT! MANUAL CHECK REQUIRED"
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1007 -Message $message -EntryType Warning
}
"No Agent found to delete"
{
$message = "NO AGENT FOUND TO DELETE BY DeleteSCOMAgent FUNCTION! MANUAL CHECK REQUIRED"
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1008 -Message $message -EntryType Warning
}
}
}
{$_ -gt $ThreshNotDelete} {
$message = "WARNING: NUMBER OF AGENTS TO REMOVE IS GREATER THAN 10 ! MANUAL CHECK REQUIRED" ## -- SECURITY OPTION TO AVOID DELETION OF TWO MANY AGENTS. BE SURE OF THE APPLIED CRITERIAS BEFORE UNLOCK THAT!
Write-Host -F red $message
$TargetComp.displayname
NewEventSource
write-eventlog -logname "Operations Manager" -Source $ScriptName -EventID 1009 -Message $message -EntryType Warning
}
}
Pour faire suite a l'article recent "SCOM - Zabbix - Management Pack pour l'agent Zabbix sur Windows" qui propose de créer et decouvrir une classe 'ZabbixAgent', voici un script permettant de faire un suivi des machines ayant l'agent Scom et l'agent Zabbix.
ScomAndZabbix.ps1 (1,20 kb)
## RETRIEVE COMPUTERS THAT HAVE SCOM AGENT AND ZABBIX AGENT
#Variables
$MGroup = "MyMG"
$MS= "MyMGServer.mydomain"
$cred = Get-Credential "ME\Myself"
#Import du module SCOM
try
{
Import-Module -Name OperationsManager -ErrorAction stop
}
catch
{
write-host -ForegroundColor red "Erreur lors de l'import du module SCOM"
}
#Connection au management group $MGroup
New-SCOMManagementGroupConnection -ComputerName $MS -Credential $cred
# Classe des "Health Service"
$AgentClass = Get-SCOMClass -DisplayName "Health Service"
# Classe des "Zabbix Agent"
$ZabbAgClass = Get-SCOMClass -DisplayName "ZabbixAgent"
# Instances de la classe $AgentClass
$AgentInst = $AgentClass | Get-SCOMClassInstance | select -Property *
# Instances de la classe $ZabbAgClass
$ZabbAgInst = $ZabbAgClass | Get-SCOMClassInstance | select -Property *
# COMPARAISON (MACHINE AYANT L'AGENT ZABBIX ET L'AGENT SCOM)
$ScomAndZab = Compare-Object -ReferenceObject $AgentInst.displayname -DifferenceObject $ZabbAgInst.path -IncludeEqual -ExcludeDifferent
Write-Host "--- MANAGEMENT GROUP SCOM: $MS ---"
write-host "--- "$ScomAndZab.count" COMPUTERS THAT HAVE SCOM AND ZABBIX ---"
$ScomAndZab.inputobject | sort
Restaurer des milliers d'éléments supprimés par une personne sur un site Sharepoint peut être une opération fastidieuse, voici donc un script Powershell pour le faire à votre place et vous bénéficierez aussi d'un rapport d'état ("Success", "Failure") pour chacun des éléments.
1 - Prérequis Powershell
Dans un premier temps nous allons avoir besoin d’installer le module Powershell nécessaire à la gestion de Sharepoint, pour ce faire utilisez la commande suivante :
# Installation du Module Powershell
Install-Module SharePointPnPPowerShellOnline
Une fois le module Powershell installé nous allons pouvoir nous connecter au site et atteindre sa corbeille de là nous pourrons faire le filtrage et l’export des éléments.
2 - Script Powershell
# Script to Restore RecycleBin elements
# By : Mathieu ADELAÏDE
# Date : 06/09/2019
# Version : V0
#######################
# Step 0 : Management #
#######################
#region - Step 0
# Folder Definition
# Get Current Path
$currentPath = (Get-Location).Path
$RootFolder = "C:\Temp\Sharepoint"
$LogFolder = "$RootFolder\Log"
#Folder Creation
$AllFolder = $RootFolder, $LogFolder
$AllFolder | foreach {
$FolderName = $_
If (!(Test-Path $FolderName)) {
New-Item $FolderName -ItemType Directory
}
}
# Files Definition
$ResultState = "$LogFolder\RestaurationReport.csv"
Add-Content $ResultState -Value "Title;ItemType;Size;ItemState;DirName;DeletedByName;DeletedDate;ID;State"
$logFilePath = "$logFolder\SP_Restauration.log"
#Define Array
$Array = @()
#Config Variables
$SiteURL = "https://MySite.sharepoint.com/sites/Recrutement"
#endregion - Step 0
#######################
# Step 1 : Connection #
#######################
#region - Step 1
#Connect to Sharepoint Online
Try {
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)
}
Catch {
$tmpError = $_.Exception.message
Write-Output "The following error occurred: $tmpError" | Add-Content $logFilePath
Write-Output "The error occurred while we trying to Connect to Sharepoint Online" | Add-Content $logFilePath
}
#endregion - Step 1
#######################################
# Step 2 : Collection and Restoration #
#######################################
#region - Step 2
# List all Items
$RecycleBin = Get-PnPRecycleBinItem
# Filter result
$FilteredRecycleBin = $RecycleBin.Where({$_.DeletedByName -eq "DUPONT Jean"})
$FilteredRecycleBin | foreach {
$Title = $_.Title
$ItemType = $_.ItemType
$Size = $_.Size
$ItemState = $_.ItemState
$DirName = $_.DirName
$DeletedByName = $_.DeletedByName
$DeletedDate = $_.DeletedDate
$ID = $_.id
$Guid = $ID.Guid
# Restore
Try {
Restore-PnPRecycleBinItem -Identity $Guid -Force -ErrorAction Stop
Write-Output "Successfully Restored File $Title" | Add-Content $logFilePath
$State = "Succes"
}
Catch {
$tmpError = $_.Exception.message
Write-Output "The following error occurred: $tmpError" | Add-Content $logFilePath
Write-Output "The error occurred while we trying to Restore $Title" | Add-Content $logFilePath
$State = "Failed"
}
$Array += New-Object psobject -Property @{
Title = $Title
ItemType = $ItemType
Size = $Size
ItemState = $ItemState
DirName = $DirName
DeletedByName = $DeletedByName
DeletedDate = $DeletedDate
State = $State
Id = $id
}
# Release variable
$Title = $null
$ItemType = $null
$Size = $null
$ItemState = $null
$DirName = $null
$DeletedByName = $null
$DeletedDate = $null
$ID = $null
$State = $null
$Guid = $null
}
#endregion - Step 2
###################
# Step 3 : Export #
###################
#region - Step 3
Try {
$Array | Export-Csv $ResultState -Encoding UTF8 -NoTypeInformation -Delimiter ";"
Write-Output "Successfully Export Data" | Add-Content $logFilePath
}
Catch {
$tmpError = $_.Exception.message
Write-Output "The following error occurred: $tmpError" | Add-Content $logFilePath
Write-Output "The error occurred while we trying to Export Data" | Add-Content $logFilePath
}
#endregion - Step 3
Récemment j’ai été confronté à un sujet délicat, une synchronisation entre Sharepoint Online et un poste client s’est terminée par la suppression de la majorité des dossiers et fichiers du site en question.
Pour pouvoir connaitre l’étendue des dégâts il a fallu faire un audit de ce qui avait été supprimés par erreur.
On pourrait le faire graphiquement via le portail, mais lorsque le nombre d’éléments s’élève à plusieurs milliers ce n’est pas pratique.
Voici une petite astuce pour faire un export au format CSV des éléments dans la corbeille et en option comment les filtrer sur un utilisateur en particulier.
1 - Prérequis Powershell
Dans un premier temps nous allons avoir besoin d’installer le module Powershell nécessaire à la gestion de Sharepoint, pour ce faire utilisez la commande suivante :
# Installation du Module Powershell
Install-Module SharePointPnPPowerShellOnline
Une fois le module Powershell installé nous allons pouvoir nous connecter au site et atteindre sa corbeille de là nous pourrons faire le filtrage et l’export des éléments.
2 - Script Powershell
2.1 Version avec tous les éléments de la corbeille.
#Config Variables
$SiteURL = "https://Monsite.sharepoint.com/sites/Recrutement"
$Items = "C:\temp\RecycleBinItems.csv"
Add-Content $Items -Value "Title;ItemType;Size;ItemState;DirName;DeletedByName;DeletedDate"
$Array = @()
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)
# List and export all Items in Recycle bin
$RecycleBin = Get-PnPRecycleBinItem
$RecycleBin | foreach {
$Title = $_.Title
$ItemType = $_.ItemType
$Size = $_.Size
$ItemState = $_.ItemState
$DirName = $_.DirName
$DeletedByName = $_.DeletedByName
$DeletedDate = $_.DeletedDate
$Array += New-Object psobject -Property @{
Title = $Title
ItemType = $ItemType
Size = $Size
ItemState = $ItemState
DirName = $DirName
DeletedByName = $DeletedByName
DeletedDate = $DeletedDate
}
}
$Array | Export-Csv $Items -Encoding UTF8 -NoTypeInformation
2.2 Version avec option de filtrage.
Dans cette version nous faisons la même requête, en ajoutant un filtrage sur un utilisateur bien précis.
#Config Variables
$SiteURL = "https://Monsite.sharepoint.com/sites/Recrutement"
$Items = "C:\temp\RecycleBinItems.csv"
Add-Content $Items -Value "Title;ItemType;Size;ItemState;DirName;DeletedByName;DeletedDate"
$Array = @()
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)
# List and export all Items in Recycle bin
$RecycleBin = Get-PnPRecycleBinItem
$FilteredRecycleBin = $RecycleBin.Where({$_.DeletedByName -eq "DUPONT Jean"})
$FilteredRecycleBin | foreach {
$Title = $_.Title
$ItemType = $_.ItemType
$Size = $_.Size
$ItemState = $_.ItemState
$DirName = $_.DirName
$DeletedByName = $_.DeletedByName
$DeletedDate = $_.DeletedDate
$Array += New-Object psobject -Property @{
Title = $Title
ItemType = $ItemType
Size = $Size
ItemState = $ItemState
DirName = $DirName
DeletedByName = $DeletedByName
DeletedDate = $DeletedDate
}
}
$Array | Export-Csv $Items -Encoding UTF8 -NoTypeInformation
La fonction ci-dessous permet de supprimer un agent scom en se connectant a distance a un management server donné.
Function Remove-SCOMAgent
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string]$MServer,
[Parameter(Mandatory=$true, Position=1)]
[string]$AgentName,
[Parameter(Mandatory=$true, Position=2)]
[string]$User,
[Parameter(Mandatory=$true, Position=3)]
[string]$Domain
)
$Cred = Get-Credential -Message "password" -Username "$Domain\$User"
#Import-Module OperationsManager
New-SCOMManagementGroupConnection -ComputerName $MServer -Credential $Cred
Start-Sleep -s 3
$administration = (Get-SCOMManagementGroup).GetAdministration();
Start-Sleep -Milliseconds 500
$agentManagedComputerType = [Microsoft.EnterpriseManagement.Administration.AgentManagedComputer];
$genericListType = [System.Collections.Generic.List``1]
$genericList = $genericListType.MakeGenericType($agentManagedComputerType)
$agentList = new-object $genericList.FullName
$agent = Get-SCOMAgent *$AgentName*
If(!($agent))
{
$message = "No agent found with name `"$AgentName`""
$message
exit
}
Start-Sleep -S 5
$agentList.Add($agent);
$genericReadOnlyCollectionType = [System.Collections.ObjectModel.ReadOnlyCollection``1]
$genericReadOnlyCollection = $genericReadOnlyCollectionType.MakeGenericType($agentManagedComputerType)
$agentReadOnlyCollection = new-object $genericReadOnlyCollection.FullName @(,$agentList);
$administration.DeleteAgentManagedComputers($agentReadOnlyCollection);
}
Remove-SCOMAgent -MServer MyMS -AgentName serv1 -User Myaccount -Domain MyDomain