PI Services

Le blog des collaborateurs de PI Services

Exchange - Redémarrage des serveurs après création du DAG

Symptômes et Diagnostic:

- Après la configuration du DAG, les serveurs Exchange redémarrent d'une manière inattendue et fréquente.

- Le message d'erreur "The computer has rebooted from a bugcheck.  The bugcheck was: 0x000000ef (0xffffe0016a359900, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000). A dump was saved in: C:\Windows\MEMORY.DMP. Report Id: 090915-32687-01" est repéré au niveau des journaux d'évènements système.

- Exécuter commande PowerShell suivante sur le serveur Exchange affecté afin de déterminer quel Probe provoquant le redémarrage des serveurs:

(Get-WinEvent -LogName Microsoft-Exchange-ManagedAvailability/* | % {[XML]$_.toXml()}).event.userData.eventXml| ?{$_.ActionID -like "*ForceReboot*"} | ft RequesterName

--> Responder ServiceHealthMSExchangeReplForceReboot entraine le redémarrage des serveurs Exchange Mailbox

- Afin de confirmer que le redémarrage du serveur est bien dû au ServiceHealthMSExchangeReplForceReboot, exécuter la commande:

Get-WinEvent -LogName Microsoft-Exchange-ManagedAvailability/* | where {$_.Message -like "*ServiceHealthMSExchangeReplForceReboot*"} | ft Message,TimeCreated

 Explications et Résolution:

- Avec le nouveau concept « Managed Availability » s’exécutant sur tous les serveurs Exchange pour surveiller l’intégrité des serveurs, ce processus analyse des centaines de mesures d’intégrité et lorsque quelque chose ne va pas se produit, une action sera appelée pour corriger ce problème.

- Dans certains cas, lorsque "Managed Availability" effectue une action de récupération à partir d’une erreur, il est intéressant de savoir quelles mesures d’intégrité "Probe" sont utilisées pour décider que le composant ou le serveur Exchange a besoin d’un correctif.

- Cause: Les cartes réseaux sont mal configurées sur les serveurs Exchange, ce qui entraîne une défaillance de la résolution du nom DNS et le redémarrage des serveurs.

- Dans ce cas de figure et pour résoudre le problème décrit ci-dessus, la case "Enregistrer les adresses de cette connexion dans le système DNS" doit être cochée.

 

 

SCCM - SQL Query - Inventaire avancé de l'état des mise a jours.

 

La requête SQL ci-dessous propose un inventaire avancé des patchs de mise a jour installés ou requis sur les machines cibles.

Les variables @StartDate et @EndDate sont utilisées pour limiter la date de création du patch.

 

	/* PATCH REQUIRED OR INSTALLED STATUS FOR ALL SERVERS WITH SOFTWARE UPDATE GROUP INFO */
	DECLARE @Collection varchar(8)
	DECLARE @StartDate DATETIME, @EndDate DATETIME
	SET @Collection = 'SMS00001' -- Collection ID for All Systems
	-- Since 1 months
	SET @StartDate = DATEADD(mm, -1,GETDATE())
	SET @EndDate = GETDATE() 
	
	SELECT DISTINCT  VRS.Name0 as 'MachineName',
	Os.Caption0 as 'OperatingSystem',
	CASE
		WHEN summ.ClientActiveStatus = 0 THEN 'Inactive' 
		WHEN summ.ClientActiveStatus = 1 THEN 'Active' 
		end as 'ClientActiveStatus',
	CASE 
		WHEN LastHealthEvaluationResult = 1 THEN 'Not Yet Evaluated' 
		WHEN LastHealthEvaluationResult = 2 THEN 'Not Applicable'
		WHEN LastHealthEvaluationResult = 3 THEN 'Evaluation Failed' 
		WHEN LastHealthEvaluationResult = 4 THEN 'Evaluated Remediated Failed' 
		WHEN LastHealthEvaluationResult = 5 THEN 'Not Evaluated Dependency Failed' 
		WHEN LastHealthEvaluationResult = 6 THEN 'Evaluated Remediated Succeeded'
		WHEN LastHealthEvaluationResult = 7 THEN 'Evaluation Succeeded'
		end as 'Last Health Evaluation Result',
	CASE 
		WHEN LastEvaluationHealthy = 1 THEN 'Pass'
		WHEN LastEvaluationHealthy = 2 THEN 'Fail'
		WHEN LastEvaluationHealthy = 3 THEN 'Unknown'
		end as 'Last Evaluation Healthy',
	CASE 
		WHEN summ.ClientRemediationSuccess = 1 THEN 'Pass' 
		WHEN summ.ClientRemediationSuccess = 2 THEN 'Fail' ELSE '' 
		end as 'ClientRemediationSuccess',
	
	
	UI.Title as 'Title',
	UI.ArticleID as 'ArticleID',
	UI.BulletinID as 'BulletinID',
	UI.DatePosted,
	UI.DateCreated,
	UI.DateLastModified,
	
	CASE UI.Severity
		WHEN 0 THEN 'None'
		WHEN 2 THEN 'Low'
		WHEN 6 THEN 'Moderate'
		WHEN 8 THEN 'Important'
		WHEN 10 THEN 'Critical'
		end as Patch_Severity,

        CASE UI.IsExpired 
		WHEN 0 THEN 'NOT EXPIRED' 
		WHEN 1 THEN 'EXPIRED' 
		END AS [EXPIRY],
	
	CASE UI.IsSuperseded 
		WHEN 0 THEN 'NOT Superseded' 
		WHEN 1 THEN 'Superseded' 
		END AS [SUPERSEDENCE],


	CASE 
		WHEN UCS.Status = 2 THEN 'Required'
		WHEN UCS.Status = 3 THEN 'Installed'
		ELSE 'Unknown' END AS 'KBStatus',
	UI.InfoURL as 'InformationURL', 
	KB_AND_SUG.Title as SoftwareUpdateGroup,

	
	CASE 
		WHEN USS.LastScanState = 0 THEN 'unknown'
		WHEN USS.LastScanState = 1 THEN 'waiting for catalog location'
		WHEN USS.LastScanState = 2 THEN 'running'
		WHEN USS.LastScanState = 3 THEN 'completed'
		WHEN USS.LastScanState = 4 THEN 'pending retry'
		WHEN USS.LastScanState = 5 THEN 'failed'
		WHEN USS.LastScanState = 6 THEN 'completed with errors'
		END as LastScanState,

	USS.ScanTime,
	USS.LastScanTime,
	USS.LastErrorCode,
	USS.LastStatusMessageID
	
	FROM v_R_System VRS
	INNER JOIN v_UpdateComplianceStatus UCS ON UCS.ResourceID = VRS.ResourceID
	INNER JOIN v_UpdateInfo UI ON UCS.CI_ID = UI.CI_ID
	INNER JOIN v_UpdateScanStatus USS on VRS.ResourceID = USS.ResourceID
	INNER JOIN v_CICategories_All CIC ON UI.CI_ID = CIC.CI_ID
	
	
	INNER JOIN v_CH_ClientSummary summ on Vrs.ResourceID = summ.ResourceID
	INNER JOIN v_GS_OPERATING_SYSTEM Os on UCS.ResourceID = Os.ResourceID
	INNER JOIN Computer_System_DATA St on UCS.ResourceID = st.MachineID
	INNER JOIN v_FullCollectionMembership Col on UCS.ResourceID = Col.ResourceID
	
/* JOINTURE POUR OBTENIR L'INFO DU SOFTWARE UPDATE GROUP AUQUEL APPARTIENS LE PATCH */
INNER JOIN (SELECT DISTINCT
		upd.ArticleID,
		AL.Title
		FROM vSMS_CIRelation as cr
		INNER JOIN fn_ListUpdateCIs(1033) upd ON  upd.CI_ID = cr.ToCIID AND cr.RelationType = 1
		INNER JOIN v_CIToContent CC ON cc.CI_ID=upd.CI_ID
		INNER JOIN v_AuthListInfo AL ON al.CI_ID =cr.FromCIID
		) KB_AND_SUG on UI.ArticleID = KB_AND_SUG.ArticleID
		
	--WHERE VRS.Operating_System_Name_and0 like '%Server%'
	AND Col.CollectionID = @Collection
	AND DateCreated BETWEEN @StartDate AND @EndDate
	--AND CategoryInstanceName = 'Security Updates' -- Only Security Updates
	
	ORDER BY DateCreated DESC
	

 

MECM (SCCM) : Windows 10 Servicing Upgrade - Problèmes connus

Dans un projet de migration de Windows 10 vers une nouvelle version en utilisant les mises à jour de fonctionnalités de Microsoft Endpoint Configuration Manager, on peut citer quelques problèmes connus et comment les corriger ou contourner.

  1. Problèmes de compatibilité
  • La version de Trend Micro n’est pas à jour (les versions inférieures à 6.7.x bloquent) > Migration bloquée

        > Solution: désinstaller Trend Micro ou mettre à jour la version

  • Client VMWare Workstation installé (les versions VMWare v12.5.7 et v12.1 ou inférieures bloquent) > Migration bloquée

        > Solution: Désinstaller VMWare Workstation Client ou mettre à jour la version installée

  • Le pilote Bluetooth Realtek n’est pas prêt pour la migration vers Windows 10 > Migration bloquée

        > Solution: Mettre à jour le pilote Bluetooth vers la version 1.5.1012 ou ultérieure

Source : <https://support.microsoft.com/en-us/help/4529832/updating-to-windows-10-version-1903-on-devices-with-some-driver-versio>

Impact sur l’utilisateur : aucun impact

  1. Le client est considéré comme conforme sans avoir vraiment installé la mise à niveau vers Windows 10
  • Vérifiez si l’ordinateur voit la mise à jour des fonctionnalités de Windows 10 comme requise dans SCCM

        > Si la mise à jour n’est pas requise, vérifiez si la langue du système d’exploitation est dans le scope de la migration ou si la version actuelle du système d’exploitation est trop vieille pour la version de mise à niveau cible

Impact sur l’utilisateur : aucun impact

  1. L’installation est « In progress » avec l’état "successfully installed update(s)"
  • Il s’agit d’un bug connu avec la version SCCM 1906 où les clients Configuration Manager détectent incorrectement l’état de cogestion

        > Solution: Installez le correctif SCCM KB4529827 (https://www.prajwaldesai.com/configuration-manager-1906-hotfix-kb4529827/)

Impact sur l’utilisateur : aucun impact

  1. Problèmes de corruption de mise à niveau
  • Erreur de délai d’expiration (l’ordinateur est trop lent ou trop utilisé pour dépasser le temps autorisé pour l’installation)
  • Erreur de travail annulée en raison de la déconnexion de l’utilisateur, du redémarrage de l’ordinateur ou de la mise en mode veille de l’ordinateur

        > Solution: attendez que le client réessaye automatiquement la tâche de mise à niveau

Impact sur l’utilisateur : aucun impact

  1. Problème de Rollback
  • Ordinateur bloqué après le redémarrage pour finaliser la mise à niveau de Windows avec les options suivantes :
    • Windows Rollback
    • Windows 10 (avec numéro de volume spécifié)
    • Windows 10 (avec numéro de volume spécifié)

        > Solution: choisissez l’option Windows Rollback

Impact sur l’utilisateur : faible impact

- Cliquez sur Windows Rollback et attendez environ 10 à 15 minutes pour récupérer l’écran de connexion Windows

 

Remarques :

  • L’impact sur l’utilisateur indique si l’utilisateur est bloqué pour travailler. S'il n'y a aucun impact c'est que l'utilisateur ne s'est même pas rendu compte du problème et que tout s'est passé en arrière plan.
  • Les fichiers log à analyser pour détecter le problème rencontré :

        - C:\Windows\CCM\Logs\UpdatesDeployment.log

        - C:\$WINDOWS.~BT\Sources\Panther\setupact.log

        - C:\$WINDOWS~BT\Sources\Panther\CompatData*.xml (le fichier le plus récemment modifié)

        N.B: "$WINDOWS~BT" est un dossier caché

MECM (SCCM) : Script de maintenance WSUS pour changer wsyncmgr purge des mises à jour expirées de 7 jours à 0 jour

Microsoft Endpoint Configuration Manager est capable de supprimer automatiquement le contenu des mises à jour logicielles des points de distribution lorsque ce contenu est lié à des mises à jour expirées. Ce processus permet de gérer l'espace disque sur vos points de distribution en supprimant tout contenu dont vous n'avez plus besoin.

Si celles-ci ne se trouvent dans aucun groupe de mises à jour logicielles, ConfigMgr purgera automatiquement les mises à jour expirées après 7 jours. Vous pouvez modifier le nettoyage à 0 jour si vous souhaitez que les composants wsyncmgr suppriment immédiatement les mises à jour expirées (en supposant qu'ils ne soient pas dans un groupe de mises à jour logicielles). On appelle ce nombre de jours, âge de nettoyage des mises à jour (Updates Cleanup Age)

Ci-dessous un script VBS qui permet de changer la valeur de l'âge de nettoyage des mises à jour sur votre ConfigMgr :

On Error Resume Next

'***  Define string variables for device, device Resource ID and user of interest

Class_Name = 		"SMS_SCI_Component"
Class_ItemName =	"SMS_WSUS_SYNC_MANAGER|<<<***CHANGEME***SCCMSERVERNAMEHERE>>>.YOURDOMAIN.COM"
Class_ItemType =	"Component"
Property_Name = 	"Updates Cleanup Age"
Property_SiteCode = 	"*****SCCMSITECODEHERE*****"
DesiredValue =		0

'***  Check parameters - we need the provider server name and the site code

set args=wscript.arguments

If args.Count = 2 then
	SMSProviderServer = UCASE(Wscript.Arguments(0))
	SiteCode = UCASE(Wscript.Arguments(1))
Else
	wscript.Echo "Incorrect command line arguments." & vbCrLf & "Usage: cscript /nologo ModifySCFProperty.vbs <smsproviderserver> <sitecode>" & vbCrLf & "Example: cscript /nologo ModifySCFProperty.vbs SERVER1 S01 > schedules.txt" & vbCrLf
	WScript.Quit(1)
End If


'***  Connect to the provider - report the error and terminate on failure

SMSProviderServer = "\\" + SMSProviderServer + "\"
Set ObjSvc = GetObject("winmgmts:" & "{impersonationLevel=Impersonate,authenticationLevel=Pkt}!" & SMSProviderServer & "root\sms\site_" & SiteCode)

If Err.Number <> 0 Then
	wscript.Echo "Failed to connect to provider server with code: " & Err.Number & ".  Aborting!"
	WScript.Quit(2)
End If

'***  Get the desired instance of the class

Set objInst = ObjSvc.Get(Class_Name & ".ItemName='" & Class_ItemName & "',ItemType='" & Class_ItemType & "',SiteCode='" & Property_SiteCode &"'")

If Err.Number <> 0 Then
	WScript.Echo "Failed to open desired object with error code " & Err.Number & " (" & Err.Description & ").  Aborting!"
	WScript.Quit(3)
End If

'***  Loop through the Properties until we find a match or run out

bFoundProperty = False

For Each objProp in objInst.Props
	If objProp.PropertyName = Property_Name Then
		bFoundProperty = True
		Exit For
	End If
Next

If bFoundProperty = False Then
	WScript.Echo "Desired object was found but property was not found.  Exiting without making any changes."
	WScript.Quit(4)
End If	

'***  Property found so check to see if existing value matches desired, changing it as appropriate

If objProp.Value = DesiredValue Then
	WScript.Echo "Property '" & Property_Name & "' found with desired value '" & DesiredValue & "'.  Not making any changes."
	WScript.Quit(0)
Else
	OriginalValue = objProp.Value
	objProp.Value = DesiredValue
	objProp.Put_
	objInst.Put_

	If Err.Number <> 0 Then
		wscript.Echo "Failed to save the desired change with code: " & Err.Number & ".  Aborting!"
		WScript.Quit(5)
	Else
		WScript.Echo "Property '" & Property_Name & "' successfully changed from '" & OriginalValue & "' to '" & DesiredValue & "'."
	End If
End If

 

Sources:

https://docs.microsoft.com/en-us/troubleshoot/mem/configmgr/software-update-maintenance

https://www.reddit.com/r/SCCM/comments/ab7v6f/software_updates_remove_old_ones/

https://youtu.be/wqBaTp855sk?t=1765

https://setupconfigmgr.com/wp-content/uploads/2018/06/Adjust-WSync_UpdateCleanupAge.zip

Powershell : Trouver la date de dernière connexion d'un utilisateur.

Comme vous le savez l'un des attributs qui nous est le plus important pour déterminer l'inactivité d'un compte est l'attribut "LastLogon", ce dernier permet de connaitre la dernière authentification valide d'un compte Active Directory.

Le problème c'est que ce dernier n'est pas répliqué entre les DCs, attention je parle bien du "LastLogon" et non le "LastLogonTimeStamp" qui lui l'est mais, ne détient pas la valeur réelle de la dernière authentification réussie.

Le "LastLogon" n'est pas répliqué entre les DCs pour une raison simple, éviter les "tempêtes" de réplication entre les DCs, imaginez, à chaque ouverture / déverrouillage de session cette valeur change, si vous pensez au nombre de fois que sont déverrouillées des sessions à la journée, cela vous donne une idée des réplications qui seraient nécessaires, par conséquent cet attribut n'est pas répliqué.

Ce qui pose donc problème c'est qu'il n'est pas possible d'avoir la réelle valeur de "LastLogon" sans devoir interroger l'intégralité des DCs et faire une comparaison de cette dernière.

Voici un script qui fera les requêtes et comparaisons pour vous, toutefois gardez à l'esprit qu'il va pour chaque utilisateur demander la valeur de l'ttribut "LastLogonà chaque DC, par conséquent ce script peut prendre plus ou moins de temps à s'exécuter en fonction du nombre d'utilisateur et du nombre de DCs.

$Array = @()
$AllDC = Get-ADDomainController -Filter * | sort Name | select Name
$AllEnabledUsers = Get-ADUser -Filter {Enabled -eq $true} | select Samaccountname

$AllEnabledUsers | select -First 5 | foreach {
    $CurrentUser = $_.Samaccountname
    $RealLastLogon = $null

    $AllDC | foreach {
        $CurrentDC = $_.Name

        Try {
            $Logon = Get-ADUser $CurrentUser -Properties LastLogon -Server $CurrentDC
            $LastLogon = [Datetime]::FromFileTime($Logon.LastLogon)
            If ($LastLogon -gt $RealLastLogon) {
                $RealLastLogon = $LastLogon
                }

            # Release variable
            $LastLogon = $null
            }
        Catch {
            Write-Warning $($_)
            }

        # Release variable
        $CurrentDC = $null
        }
    
    # Store Data
    $Array += New-Object psobject -Property @{
        DistinguishedName = $Logon.DistinguishedName
        Enabled = $Logon.Enabled
        GivenName = $Logon.GivenName
        Name = $Logon.Name
        ObjectClass = $Logon.ObjectClass
        ObjectGUID = $Logon.ObjectGUID
        SamAccountName = $Logon.SamAccountName
        SID = $Logon.SID
        Surname = $Logon.Surname
        UserPrincipalName = $Logon.UserPrincipalName
        LastLogon = $RealLastLogon
        }
        
    # Release Variables
    $CurrentUser = $null
    $RealLastLogon = $null
    }

Il ne vous restera qu'a examiner la sortie en rappelant la variable "$Array" ou à l'exporter dans un CSV comme ci-dessous par exemple.

$Array | Export-Csv C:\Temp\AllUsersWithLastLogon.csv -Delimiter ";" -Encoding UTF8 -NoTypeInformation

 

Si la valeur "LastLogon" est égale à "01/01/1601 01:00:00" cela veut dire que le compte ne s'est jamais connecté

Script - API Vmware VCenter - Get VM infos

Le script ci-dessous est un exemple simple de l'utilisation de l'API Rest de Vcenter pour recuperer toute sorte d'information, nottament sur les machines virtuelles.

A noter que la limitation du nombre d'objet retournés oblige simplement a recuperer dans un premier temps la liste des hosts, puis par host la liste des VMs.

 

### QUERY VCENTER REST API TO GET VM LIST ###


$user = ‘myaccount’
$pswd = Read-Host -Prompt "Enter Password"
$vCenterName = ‘MyVcenter’
$encoded = [System.Text.Encoding]::UTF8.GetBytes(($user, $pswd -Join ‘:’))
$encodedPassword = [System.Convert]::ToBase64String($Encoded)
$authHeader = @{
Authorization = "Basic $($EncodedPassword)"
}
$sRest = @{
Method = ‘Post’
Uri = "https://$($vCenterName)/rest/com/vmware/cis/session"
Headers = $authHeader
}
$result = Invoke-RestMethod @sRest


# Get TokenID
$authHeader = @{
‘vmware-api-session-id’ = $result.value
}


# Get All Hosts
$gethosts = "https://$($vCenterName)/rest/vcenter/host"
$resultgethost = Invoke-RestMethod -Uri $gethosts -Headers $authHeader
$hostidlist = $resultgethost.value.host


# For each host, get all VMs

foreach ($hostid in $hostidlist)
{
$get_vm = "https://$($vCenterName)/rest/vcenter/vm?filter.hosts=$hostid"
$resultvm = Invoke-RestMethod -Uri $get_vm -Headers $authHeader
[array]$FinalTableau += $resultvm
}

# Display Result
$FinalTableau.value | select name,power_state


# Output to CSV
$CsvTab = $FinalTableau.value | select name,power_state | ConvertTo-Csv -Delimiter ';' -NoTypeInformation
$CsvTab | Out-File .\VMList.csv

 

 

 

 

Powershell : Comparer une date manuellement saisie avec un format spécifique à la date du last logon d'un utilisateur dans Active Directory

Dans le cadre de l'automatisation, il arrive de recevoir une demande pour développer un script PowerShell pour le nettoyage ou la gestion de l'obsolescence des utilisateurs dans l'Active Directory.

Dans le script, vous aurez peut être besoin de comparer la date du last logon utilisateur dans l'Active Directory avec une date manuellement saisie (variable du script) avec un format spécifique.

Ci-dessous un exemple de PowerShell pour comparer une date donnée avec une date de last logon utilisateur dans Active Directory :

# Import Active Directory Module
Import-Module ActiveDirectory
 
#Set a fixed date for comparison
$Fixed_Date = "13/11/2021"
 
#Convert the fixed date from a string to a compatible specific format
$Fixed_Date_Convert = [datetime]::parseexact($Fixed_Date, 'dd/MM/yyyy', $null)  
 
#Get AD user last logon date in dd/MM/yyyy format
$ADUser = get-aduser "jdoe" -Properties lastlogondate | select @{Name=”ModifiedLastLogonDate”;Expression={$_.LastLogonDate.ToString(“dd/MM/yyyy”)}}
 
#Convert AD last logon date to a specific format to be compared with the chosen date above
$ADdate = [datetime]::parseexact($ADUser.ModifiedLastLogonDate, 'dd/MM/yyyy', $null)
 
if($ADdate -le $Fixed_Date_Convert)
    {
        echo "Active directory last logon date is inferior to the fixed date"
        }
    else
    {
        echo "Active directory last logon date is superior to the fixed date"
        }

Conclusion:

La méthode [datetime]::parseexact(dateString, format, provider) Convertit la représentation sous forme de chaîne spécifiée d'une date et d'une heure en son équivalent DateTime.

SCCM - SQL Queries - Deployments,Assignments,Updates

Ci-dessous, une série de requêtes SQL sur les déploiements, les assignations et les mise a jours.

/**** QUERIES: DEPLOYMENTS,ASSIGNMENTS,UPDATES ****/


--- LIST OF DEPLOYMENTS NAME
SELECT 
--DeploymentID = cia.Assignment_UniqueID,
DeploymentName = isnull(grp.Title+' - ', '') + cia.AssignmentName
FROM [dbo].[vCI_CIAssignments]  CIA
LEFT JOIN [dbo].[vCI_AssignmentTargetedGroups]  ATG on CIA.AssignmentType=5 and ATG.AssignmentID=CIA.AssignmentID
LEFT JOIN [dbo].[v_AuthListInfo] GRP on CIA.AssignmentType=5 and GRP.CI_ID=ATG.AssignedUpdateGroup
WHERE CIA.AssignmentType in (1,5)




--- LIST OF ASSIGNMENTS NAME WITH RELATED DEPLOYMENTS NAME
SELECT 
--AssignmentID,
CIA.AssignmentName,
--,DEPLOY.DeploymentID,
DEPLOY.DeploymentName 

FROM v_CIAssignment CIA
INNER JOIN (
			SELECT DeploymentID = cia.Assignment_UniqueID
			, DeploymentName = isnull(grp.Title+' - ', '') + cia.AssignmentName
			FROM [dbo].[vCI_CIAssignments]  CIA
			LEFT JOIN[dbo].[vCI_AssignmentTargetedGroups]  ATG on CIA.AssignmentType=5 and ATG.AssignmentID=CIA.AssignmentID
			LEFT JOIN [dbo].[v_AuthListInfo] GRP on CIA.AssignmentType=5 and GRP.CI_ID=ATG.AssignedUpdateGroup
			WHERE CIA.AssignmentType in (1,5)

			) DEPLOY on DEPLOY.DeploymentID = CIA.Assignment_UniqueID



---- LIST OF UPDATES 

		SELECT DISTINCT 
		--CI_UniqueID,
		DisplayTitle = ui.Title+isnull(' ('+nullif(ui.ArticleID, '')+')', '') + isnull(' ('+nullif(ui.BulletinID, '') +')', '')
		,DateCreated
		, (CASE ui.Severity 
		WHEN 0 THEN 'NONE' 
		WHEN 2 THEN 'LOW' 
		WHEN 6 THEN 'MODERATE' 
		WHEN 8 THEN 'IMPORTANT' 
		WHEN 10 THEN 'CRITICAL' END) AS SEVERITY
		FROM v_UpdateInfo UI
		
		ORDER BY DateCreated DESC

        

---- LIST OF UPDATES AND RELATED ASSIGNMENTS NAME

		SELECT DISTINCT 
		--CI_UniqueID,
		DisplayTitle = ui.Title+isnull(' ('+nullif(ui.ArticleID, '')+')', '') + isnull(' ('+nullif(ui.BulletinID, '') +')', '')
		,DateCreated
		,(CASE ui.Severity 
			WHEN 0 THEN 'NONE' 
			WHEN 2 THEN 'LOW' 
			WHEN 6 THEN 'MODERATE' 
			WHEN 8 THEN 'IMPORTANT' 
			WHEN 10 THEN 'CRITICAL' END) AS SEVERITY
		,CIA.AssignmentName
		FROM v_CIAssignment CIA
		INNER JOIN v_CIAssignmentToCI  ATC on ATC.AssignmentID=CIA.AssignmentID
		INNER JOIN v_UpdateInfo UI on UI.CI_ID=ATC.CI_ID

		ORDER BY DateCreated DESC
		
		



---- LIST OF UPDATES AND RELATED DEPLOYMENTS NAME

		SELECT 
		--CI_UniqueID,
		DisplayTitle = ui.Title+isnull(' ('+nullif(ui.ArticleID, '')+')', '') + isnull(' ('+nullif(ui.BulletinID, '') +')', '')
		,UI.DateCreated
		,(CASE ui.Severity 
			WHEN 0 THEN 'NONE' 
			WHEN 2 THEN 'LOW' 
			WHEN 6 THEN 'MODERATE' 
			WHEN 8 THEN 'IMPORTANT' 
			WHEN 10 THEN 'CRITICAL' END) AS SEVERITY
		,DEPLOY.DeploymentName
		FROM v_CIAssignment CIA
		INNER JOIN v_CIAssignmentToCI  ATC on ATC.AssignmentID=CIA.AssignmentID
		INNER JOIN v_UpdateInfo UI on UI.CI_ID=ATC.CI_ID
		INNER JOIN (
					SELECT DeploymentID = cia.Assignment_UniqueID
					, DeploymentName = isnull(grp.Title+' - ', '') + cia.AssignmentName
					FROM [dbo].[vCI_CIAssignments]  CIA
					LEFT JOIN [dbo].[vCI_AssignmentTargetedGroups]  ATG on CIA.AssignmentType=5 and ATG.AssignmentID=CIA.AssignmentID
					LEFT JOIN [dbo].[v_AuthListInfo] GRP on CIA.AssignmentType=5 and GRP.CI_ID=ATG.AssignedUpdateGroup
					WHERE CIA.AssignmentType in (1,5)

					) DEPLOY on DEPLOY.DeploymentID = CIA.Assignment_UniqueID
			
		ORDER BY DateCreated DESC

	

 

 

MEM / Intune : Configurer Google Chrome à l'aide de l'ingestion ADMX

La configuration des paramètres de stratégie de Microsoft Edge dans Microsoft Intune peut être gérée par le profil de modèles d'administration déjà intégré.

Si vous souhaitez gérer les paramètres de stratégie de Google Chrome dans Microsoft Intune, ils ne sont actuellement pas disponible dans les modèle d'administration. Dans ce cas, la solution est de configurer Google Chrome avec des paramètres personnalisés pour les appareils Windows 10 et versions ultérieures dans Intune.

La configuration se passe en deux étapes :

1. Ingérer le fichier ADMX Google Chrome dans Intune

Pour ingérer le fichier ADMX, procédez comme suit :

- Téléchargez les modèles ADMX Chrome

- Connectez-vous au portail Microsoft Azure

- Accédez à Intune puis Périphériques puis Profils de configuration

- Dans la barre de commandes supérieure, sélectionnez + Créer profil

Sélectionnez un profil personnalisé (Custom) ensuite cliquez sur créer et choisissez un nom dans le menu suivant.

Dans la configuration des paramètres OMA-URI, saisissez le texte suivant :

  • Nom
    Google Chrome ADMX ingestion
  • Description
    Saisir une description (facultatif)
  • OMA-URI
    ./Device/Vendor/MSFT/Policy/ConfigOperations/ADMXInstall/Chrome/Policy/ChromeAdmx
  • Type de données
    Chaîne (à sélectionner dans la liste déroulante)

Une fois que vous avez sélectionné Chaîne, un champ de texte intitulé Valeur s'affiche en bas. Vous allez trouver le contenu de ce champ texte dans le fichier chrome.admx qui se trouve dans le fichier .zip que vous avez déjà téléchargé (modèles ADMX Chrome) sous le chemin suivant : Configuration/admx/chrome.admx.

Cliquez sur Save.

2. Définir une stratégie à l'aide d'un OMA-URI personnalisé dans Intune

Sur le même profil, on peut ajouter des OMA-URI personnalisé pour définir des stratégies de Google Chrome.

Pour ajouter des paramètres de stratégie Google Chrome, vous devez ouvrir le profil déjà créé pour ingérer l'ADMX, ensuite cliquer sur Propriétés, puis sur Modifier les Paramètres de configuration.

Dans cet exemple, nous allons ajouter un paramètre OMA-URI personnalisé afin d'autoriser les Popup dans Chrome pour "piservices.fr".

Dans le menu suivant, cliquez sur Ajouter

Dans le menu suivant, indiquez les informations suivantes :

  • Nom
    CHROME Allow Popup
  • Description
    Saisir une description (facultatif)
  • OMA-URI
    ./Device/Vendor/MSFT/Policy/Config/Chrome~Policy~googlechrome~ContentSettings/PopupsAllowedForUrls
  • Type de données
    Chaîne (à sélectionner dans la liste déroulante)
  • Valeur

    <enabled/>

    <data id="PopupsAllowedForUrlsDesc" value="1&#xF000;[*.]piservices.fr"/>a

Cliquez sur Save.

 

Sources :

Gérer le navigateur Chrome avec Microsoft Intune - Aide Google Chrome Enterprise

Configurer Microsoft Edge à l’aide de Gestion des périphériques mobiles | Microsoft Docs

Script - Invoquer un update d'un agent Trend OSC a distance

Le script ci-dessous propose d'utiliser a distance la commande "PccNTMon.exe -u" sur un agent Trend OSC pour invoquer une mise a jour, en direction de son serveur OSC de rattachement.

 

#### RemoteInvokeTrendOSCAgentUpdate.ps1: REMOTELY INITIATE AN UPDATE OF A TREND OSC AGENT ####

## COMMENT: The script execute command through PSSession and open a RDP window to allow interactive use of "OSCAgentExe -u" ###

param(
# Target Computer
$Computer = "MyTarget",
# Cred
$Cred = $(Get-Credential -Credential "MyAccount"),
# OSC Agent Folder
$OSCAgentFolder = "C:\Program Files (x86)\Trend Micro\OfficeScan Client\",
# OSC Client Process
$OSCClientProc = "PccNTMon"
)


# OSC Agent Exe
$OSCAgentExe = "$OSCAgentFolder$OSCClientProc`.exe"


# FUNCTIONS
function Set-WindowState {
	
	[CmdletBinding(DefaultParameterSetName = 'InputObject')]
	param(
		[Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)]
		[Object[]] $InputObject,

		[Parameter(Position = 1)]
		[ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE',
					 'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED',
					 'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')]
		[string] $State = 'SHOW'
	)

	Begin {
		$WindowStates = @{
			'FORCEMINIMIZE'		= 11
			'HIDE'				= 0
			'MAXIMIZE'			= 3
			'MINIMIZE'			= 6
			'RESTORE'			= 9
			'SHOW'				= 5
			'SHOWDEFAULT'		= 10
			'SHOWMAXIMIZED'		= 3
			'SHOWMINIMIZED'		= 2
			'SHOWMINNOACTIVE'	= 7
			'SHOWNA'			= 8
			'SHOWNOACTIVATE'	= 4
			'SHOWNORMAL'		= 1
		}

		$Win32ShowWindowAsync = Add-Type -MemberDefinition @'
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
'@ -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru

		if (!$global:MainWindowHandles) {
			$global:MainWindowHandles = @{ }
		}
	}

	Process {
		foreach ($process in $InputObject) {
			if ($process.MainWindowHandle -eq 0) {
				if ($global:MainWindowHandles.ContainsKey($process.Id)) {
					$handle = $global:MainWindowHandles[$process.Id]
				} else {
					Write-Error "Main Window handle is '0'"
					continue
				}
			} else {
				$global:handle = $process.MainWindowHandle
			}

			$Win32ShowWindowAsync::ShowWindowAsync($handle, $WindowStates[$State]) | Out-Null
			Write-Verbose ("Set Window State '{1} on '{0}'" -f $handle, $State)
		}
	}
}




# FOR EACH COMPUTER
foreach ($Comp in $Computer) {


# Create PSSession
try
{
New-PSSession -ComputerName $Comp -Credential $Cred -Name "PSSession_$Comp" -ErrorAction Stop
}
catch
{
write-host -F Red "Error during New-PSSession `n $($Error[0].Exception)"
exit 1 
}


# Get PSsession
$RemoteSession = Get-PSSession -Name "PSSession_$Comp"


# Open RDP Session (needed because the invoke update is interactive)
cmdkey /generic:TERMSRV/$Comp /user:($Cred.UserName) /pass:($Cred.GetNetworkCredential().Password)

mstsc /v:$Comp /w:50 /h:50

Write-Host "Wait for 10 sec..."
Start-Sleep -Seconds 10


# Get the RDP process Id to kill it at the end
$ProcId = (Get-Process mstsc | Where-Object {$_.MainWindowTitle -like "*$Comp*"}).Id


# Minimize RDP Window
(Get-Process mstsc | Where-Object {$_.MainWindowTitle -like "*$Comp*"}) | foreach {Set-WindowState $_ HIDE}


Write-Host "Wait for 10 sec..."
Start-Sleep -Seconds 10



# Invoke Update
write-host "Invoking update..."
Invoke-Command -Session $RemoteSession -ScriptBlock {Start-Process -FilePath $Using:OSCAgentExe -ArgumentList "-u"} 


        # Wait while update (see for update of ofcscan.ini file)
        do {
            Write-Host "Wait while update..."
           }

        until

           (
            (Invoke-Command -Session $RemoteSession -ScriptBlock {Get-ChildItem -Path "$Using:OSCAgentFolder`ofcscan.ini" | Where-Object {$_.LastWriteTime -gt $(get-date).AddMinutes(-15)}})
           )


Write-Host "Wait for 10 sec..."
Start-Sleep -Seconds 10



# Close RDP Session
write-host "Logoff RDP Session on $Comp..."
Invoke-Command -Session $RemoteSession -ScriptBlock {`
    $CredUser = $($Using:Cred.UserName)
    $sessions = quser | Where-Object {$_ -match $CredUser} ; 
    $sessionIds = ($sessions -split ' +')[2] ; 
    Write-Host "Found $(@($sessionIds).Count) user login(s) on computer.";
    $sessionIds | ForEach-Object {Write-Host "Logging off session id [$($_)]..." ; logoff $_}
     
     }


# Close RDP Session Disconnect Window by killing process
Get-Process -Id $ProcId | stop-process


}

# Remove Pssession
Get-PSSession | Remove-PSSession