PI Services

Le blog des collaborateurs de PI Services

Script - Powershell et SCCM Query pour determiner des listes de roles applicatifs

Le script ci-dessous utilise une requete SQL SCCM issue d'un precedent post, enrichie d'une autre vue, pour determiner, a partir du resultat de la requete, des roles applicatifs de serveurs, et en generer des listes de serveurs correspondants.

D'autres roles peuvent etre ajouté dans la section "Sous-Regroupements", pour enrichir les listes de roles.

NB: La variable $Result qui est le resultat direct de la requete SQL contiens tout les éléments (exe, add-remove-program, services), par serveur, permettant de determiner d'autres roles.

 

########################################################################################################
### REQUETE LA BASE SQL DE SCCM POUR OBTENIR LA LISTE DES APPLICATIONS ET EXECUTABLES DES ASSETS SERVEURS.
### EN FONCTION DES RESULTATS, GENERATION DE LISTES DE SERVEURS PAR ROLES APPLICATIFS (IIS,SQL ...).
### EXPORT DES RESULTAT EN FICHIER CSV  #####
######################################################################################################## 


<# 

    .SYNOPSIS 
        REQUETE LA BASE SQL DE SCCM POUR OBTENIR LA LISTE DES APPLICATIONS ET EXECUTABLES DES ASSETS SERVEURS.
        EN FONCTION DES RESULTATS, GENERATION DE LISTES DE SERVEURS PAR ROLES APPLICATIFS (IIS,SQL ...).
        EXPORT DU RESULTAT EN FICHIER CSV.

    .PARAMETER  
        SQLInstance : Instance SQL
        SQLDB : Instance SQL
        SQLQuery : Requete SQL
        ExportFolder : Dossier d'export du fichier CSV
        LogFolder : Chemin du dossier où creer le log du script

 
    .EXAMPLE 
     .\SCCM_Roles_And_Apps.ps1 -SQLInstance MyServer -SQLDB CM_BIM -ExportFolder D:\ExportCSV -LogFolder D:\ExportCSV
#>


[CmdletBinding()]
param(
[Parameter(Mandatory=$true,HelpMessage="Instance SQL")]
[string]$SQLInstance,

[Parameter(Mandatory=$true,HelpMessage="Base SQL")]
[string]$SQLDB,

[Parameter(Mandatory=$false,HelpMessage="Requete SQL")] 
[string]$SQLQuery= $("/* --- SERVER SOFTWARES, EXECUTABLES, AND SERVICES(NT) INVENTORY ---  
 NB: UNION ENTRE LES VUES:
	 [v_GS_INSTALLED_SOFTWARE_CATEGORIZED] 
	 [v_GS_INSTALLED_EXECUTABLE]
	 [v_ADD_REMOVE_PROGRAMS]
	 [v_GS_SERVICE]

	       
 NB: DES COLONNES SONT CREES ET POSITIONNEE A NULL POUR POUVOIR EFFECTUER LE UNION. (Meme nombre de colonnes) 

L'UNION ENTRE LES VUES EST REGROUPEE DANS UNE TABLE 'TAB' (CLAUSE 'WITH').
LA REQUETE FINALE EST EXECUTEE SUR LA TABLE 'TAB'


v_GS_INSTALLED_SOFTWARE_CATEGORIZED
Répertorie des informations sur les applications logicielles installées sur Configuration Manager clients trouvés via Asset Intelligence. 
Cette vue contient les informations contenues dans le v_GS_INSTALLED_SOFTWARE afficher et joint plusieurs autres tables pour fournir des détails supplémentaires sur les logiciels installés.

v_GS_INSTALLED_EXECUTABLE
Répertorie des informations sur les fichiers exécutables de l’application logicielle installée sur Configuration Manager clients trouvés via Asset Intelligence.

[v_ADD_REMOVE_PROGRAMS]
Combination of 32 and 64 bit programs data in 'Add Remove Programs'

[v_GS_SERVICE]
Services NT des Machines Windows

*/



DECLARE @CollectionID as Varchar(8)
SET @CollectionID = 'SMS00001' --Specify the collection ID
;


WITH TAB (
ResourceID
,ProductCode
,Machine_Name
,OS_Name
,Publisher
,NormalizedPublisher
,ExecutableName
,ServiceName
,ServicePath
,Service_Description
,Service_StartMode
,Service_StartName
,ProductName
,AddRemove_Name
,NormalizedName
,FamilyName
,CategoryName
,ProductVersion
,InstallDate
,Soft_Autostart
,EXE_FilePath
,EXE_Description
,EXE_FileVersion
)

AS (




SELECT 
SYST.ResourceID,
UPPER(SOFT.ProductCode0) as ProductCode,
SYST.Name0 as Machine_Name,

-- OS Info --
OS.Caption0 as OS_Name,

-- SOFT INFO --
SOFT.Publisher0 as Publisher
,SOFT.NormalizedPublisher
,NULL as ExecutableName
,NULL as ServiceName
,NULL as ServicePath
,NULL as Service_StartMode
,NULL as Service_StartName
,NULL as Service_Description
,SOFT.ProductName0 as ProductName
,NULL as AddRemove_Name,
SOFT.NormalizedName,
SOFT.FamilyName,
SOFT.CategoryName,
SOFT.ProductVersion0 as ProductVersion,


SOFT.InstallDate0 as InstallDate,


CASE 
	WHEN AUTOSTART_SOFT.Product0 IS NULL THEN 'NO'
	ELSE 'YES'
	END as Soft_Autostart,

NULL as EXE_FilePath,
NULL as EXE_Description,
NULL as EXE_FileVersion


FROM [dbo].[v_GS_INSTALLED_SOFTWARE_CATEGORIZED] SOFT
FULL JOIN v_R_System SYST on SYST.ResourceID = SOFT.ResourceID
FULL JOIN [dbo].[v_GS_OPERATING_SYSTEM] OS on OS.ResourceID = SYST.ResourceID
FULL JOIN [dbo].[v_GS_AUTOSTART_SOFTWARE] AUTOSTART_SOFT on AUTOSTART_SOFT.Product0 = SOFT.ProductName0   -- TO MAKE RELATION WITH AUTO-START SOFTWARE
FULL JOIN v_FullCollectionMembership on (v_FullCollectionMembership.ResourceID = SYST.ResourceID)

WHERE v_FullCollectionMembership.CollectionID = @CollectionID


  
UNION 
 

SELECT 
  

SYST.ResourceID,
UPPER(EXE.ProductCode0) as ProductCode,
SYST.Name0 as 'Machine Name'

-- OS Info --
,OS.Caption0 as OS_Name

,EXE.Publisher0 as Publisher
,NULL as NormalizedPublisher
,EXE.ExecutableName0 as ExecutableName
,NULL as ServiceName
,NULL as ServicePath
,NULL as Service_StartMode
,NULL as Service_StartName
,NULL as Service_Description
,EXE.Product0 as ProductName
,NULL as AddRemove_Name
,NULL as NormalizedName
,NULL as FamilyName
,NULL as CategoryName 
,EXE.ProductVersion0 AS ProductVersion
,NULL as InstallDate
,NULL as Soft_Autostart

,EXE.InstalledFilePath0 as EXE_FilePath
,EXE.Description0 as EXE_Description
,EXE.FileVersion0 AS EXE_FileVersion


FROM [dbo].[v_GS_INSTALLED_EXECUTABLE] EXE
  
  FULL JOIN v_R_System SYST on SYST.ResourceID = EXE.ResourceID
  FULL JOIN [dbo].[v_GS_OPERATING_SYSTEM] OS on OS.ResourceID = SYST.ResourceID
  FULL JOIN v_FullCollectionMembership on (v_FullCollectionMembership.ResourceID = SYST.ResourceID)
  --FULL JOIN [dbo].[v_GS_SERVICE] SERVICE_NT on SERVICE_NT.ResourceID = SYST.ResourceID
 
 WHERE v_FullCollectionMembership.CollectionID = @CollectionID
 
  
  
UNION


SELECT
ARP.ResourceID
,UPPER(ARP.ProdID0) as ProductCode
,SYST.Name0 as 'Machine Name'
-- OS Info --
,OS.Caption0 as OS_Name
,ARP.Publisher0 as Publisher
,NULL as NormalizedPublisher
,NULL as ExecutableName
,NULL as ServiceName
,NULL as ServicePath
,NULL as Service_StartMode
,NULL as Service_StartName
,NULL as Service_Description
,NULL as ProductName
,ARP.DisplayName0 as AddRemove_Name
,NULL as NormalizedName
,NULL as FamilyName
,NULL as CategoryName 
,ARP.Version0 AS ProductVersion 

,CASE
WHEN ISDATE(ARP.InstallDate0) <> 0 THEN CONVERT(date,ARP.InstallDate0)
WHEN ISDATE(ARP.InstallDate0) = 0 THEN NULL
END AS InstallDate

,NULL as Soft_Autostart
,NULL as EXE_FilePath
,NULL as EXE_Description
,NULL as EXE_FileVersion

FROM [dbo].[v_ADD_REMOVE_PROGRAMS] ARP
FULL JOIN v_R_System SYST on SYST.ResourceID = ARP.ResourceID  
FULL JOIN v_FullCollectionMembership on (v_FullCollectionMembership.ResourceID = SYST.ResourceID)
--FULL JOIN [dbo].[v_GS_SERVICE] SERVICE_NT on SERVICE_NT.ResourceID = SYST.ResourceID
INNER JOIN [dbo].[v_GS_OPERATING_SYSTEM] OS on OS.ResourceID = SYST.ResourceID  

WHERE v_FullCollectionMembership.CollectionID = @CollectionID 


UNION 
 

SELECT 

SERVICE_NT.ResourceID,
NULL as ProductCode,
SYST.Name0 as 'Machine Name'

-- OS Info --
,OS.Caption0 as OS_Name

,NULL as Publisher
,NULL as NormalizedPublisher
,NULL as ExecutableName
,SERVICE_NT.Name0 as ServiceName
,SERVICE_NT.PathName0 as ServicePath
,SERVICE_NT.Description0 as Service_Description
,SERVICE_NT.StartMode0 as Service_StartMode
,SERVICE_NT.StartName0 as Service_StartName
,NULL as ProductName
,NULL as AddRemove_Name
,NULL as NormalizedName
,NULL as FamilyName
,NULL as CategoryName 
,NULL as ProductVersion
,NULL as InstallDate
,NULL as Soft_Autostart
,NULL as EXE_FilePath
,NULL as EXE_Description
,NULL AS FileVersion


FROM [dbo].[v_GS_SERVICE] as SERVICE_NT
  
  FULL JOIN v_R_System SYST on SYST.ResourceID = SERVICE_NT.ResourceID
  FULL JOIN [dbo].[v_GS_OPERATING_SYSTEM] OS on OS.ResourceID = SYST.ResourceID
  FULL JOIN v_FullCollectionMembership on (v_FullCollectionMembership.ResourceID = SYST.ResourceID)
 
 WHERE v_FullCollectionMembership.CollectionID = @CollectionID

 
  
  ) 
  

 
 SELECT  DISTINCT 

TAB.ResourceID
,TAB.Machine_Name
,TAB.OS_Name

/*-- EXEMPLES DE COLONNE CUSTOM SELON DES VALEURS
,CASE

	WHEN (TAB.ServiceName = 'W3SVC' and TAB.Service_StartMode = 'Auto') THEN 'YES'
	ELSE NULL
	END AS 'IS_IIS'
	
,CASE

	WHEN (TAB.AddRemove_Name like 'SQL Server%Database Engine Services') THEN 'YES'
	ELSE NULL
	END AS 'IS_MSSQL_DBENGINE'  


,CASE

	WHEN (TAB.AddRemove_Name like 'SQL Server%Reporting Services') THEN 'YES'
	ELSE NULL
	END AS 'IS_MSSQL_RS'  
*/

,TAB.Publisher
,TAB.NormalizedPublisher
,TAB.ExecutableName
,TAB.ServiceName
,TAB.ServicePath
,TAB.Service_Description
,TAB.Service_StartMode
,TAB.Service_StartName
,TAB.ProductName
,TAB.ProductCode
,TAB.AddRemove_Name
,TAB.NormalizedName
,TAB.FamilyName
,TAB.CategoryName





,CASE
	
	WHEN TAB.ProductVersion like '[0-9][.][0-9][.][0-9][-]%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '[0-9][.][0-9][.][0-9][a-z]' THEN SUBSTRING(TAB.ProductVersion,0,5)
	WHEN TAB.ProductVersion like '[0-9][.][0-9][.][0-9][a-z]%' THEN SUBSTRING(TAB.ProductVersion,0,5)
	WHEN TAB.ProductVersion like '[0-9][.][0-9][.][0-9][0-9][0-9][0-9][a-z]%' THEN SUBSTRING(TAB.ProductVersion,0,5)
	WHEN TAB.ProductVersion like '[0-9][.][0-9][.][0-9][.]%[a-z]%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '[0-9][0-9][.][0-9][.]%[a-z]%' AND TAB.EXE_FileVersion IS NOT NULL THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '[0-9][0-9][.][0-9][0-9][.][a-z]%' AND TAB.EXE_FileVersion IS NULL THEN SUBSTRING(TAB.ProductVersion,0,5)
	WHEN TAB.ProductVersion like '[0-9][.][0-9][0-9][.][a-zA-Z]%' AND TAB.EXE_FileVersion IS NULL THEN SUBSTRING(TAB.ProductVersion,0,4)
	WHEN TAB.ProductVersion like '[0-9][.][0-9][0-9][.][0-9][0-9][0-9][.][0-9]%[0-9][0-9][.][0-9][0-9]%)' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '[0-9][.][0-9][0-9][.][0-9][0-9][0-9][0-9][.][0-9][0-9][0-9]%[0-9][0-9][.][0-9][0-9]%)' THEN TAB.EXE_FileVersion
	
	WHEN TAB.ProductVersion = 'Unidentified build' THEN NULL
	WHEN TAB.ProductVersion like '%.FR' THEN REPLACE(TAB.ProductVersion,'.FR','')
	WHEN TAB.ProductVersion like '%.RR' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%Release%' THEN REPLACE(TAB.ProductVersion,'Release','')
	WHEN TAB.ProductVersion like '%bet%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%build%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%Eagle%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%Impala%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%Summer%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%sum%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like 'S%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%c40%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%b5%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%59d%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%ffbc%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%2d6%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%7d7%' THEN TAB.EXE_FileVersion
	
	WHEN TAB.ProductVersion like '%Unversioned%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%rd_store_sdk%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion like '%[/]%' THEN SUBSTRING(TAB.ProductVersion,LEN(SUBSTRING(TAB.ProductVersion,0,LEN(TAB.ProductVersion) - CHARINDEX(' ',TAB.ProductVersion)+1))+1, LEN(TAB.ProductVersion) - LEN(SUBSTRING(TAB.ProductVersion,0,LEN(TAB.ProductVersion) - CHARINDEX(' ',TAB.ProductVersion))))
	WHEN TAB.ProductVersion like '%BLD%' THEN SUBSTRING(TAB.ProductVersion,0,5)
	WHEN TAB.ProductVersion like '%PQ%' THEN TAB.EXE_FileVersion
	WHEN TAB.ProductVersion = 'sonicmf.exe' THEN NULL
	WHEN TAB.ProductVersion = 'Unidentified build' THEN NULL
	WHEN TAB.ProductVersion like '%A%' THEN REPLACE(TAB.ProductVersion,'A','')
	WHEN TAB.ProductVersion like 'xxx%' THEN NULL
	WHEN TAB.ProductVersion like '%c' THEN REPLACE(TAB.ProductVersion,'c','')
	WHEN TAB.ProductVersion like '%k' THEN REPLACE(TAB.ProductVersion,'k','')
	WHEN TAB.ProductVersion like '%g' THEN REPLACE(TAB.ProductVersion,'g','')
	WHEN TAB.ProductVersion like '%.windows%' THEN SUBSTRING(TAB.ProductVersion,0,6)
	WHEN TAB.ProductVersion like '%beta%' THEN REPLACE(TAB.ProductVersion,'beta','')
	WHEN TAB.ProductVersion like '%Release%' THEN REPLACE(TAB.ProductVersion,'Release','')
	WHEN TAB.ProductVersion like '%NotilusWeb%' THEN REPLACE(TAB.ProductVersion,'NotilusWeb','')
	WHEN TAB.ProductVersion like '%WUG%' THEN REPLACE(TAB.ProductVersion,'WUG','')
	WHEN TAB.ProductVersion like '%[ ]%' THEN REPLACE(TAB.ProductVersion,' ','')
	
	WHEN TAB.EXE_Description = 'Windows Admin Center Windows Service' THEN TAB.EXE_FileVersion
	WHEN TAB.EXE_Description like '%ServiceHub.Host.CLR%' THEN TAB.EXE_FileVersion
	WHEN TAB.EXE_Description like '%Microsoft.ServiceHub.Controller%' THEN TAB.EXE_FileVersion
	WHEN TAB.EXE_Description like '%Microsoft Mashup%' THEN TAB.EXE_FileVersion
	WHEN TAB.EXE_Description like '%Element programu Soneta%' THEN TAB.EXE_FileVersion

		
	
	
	ELSE TAB.ProductVersion
	END AS ProductVersion


,TAB.InstallDate
,TAB.Soft_Autostart
,TAB.EXE_FilePath
,TAB.EXE_Description


,CASE
	
	WHEN TAB.EXE_FileVersion like '%build%' THEN NULL
	WHEN TAB.EXE_FileVersion like '%beta%' THEN REPLACE(TAB.EXE_FileVersion,'beta','')
	WHEN TAB.EXE_FileVersion like '%Release%' THEN REPLACE(TAB.EXE_FileVersion,'Release','')
	WHEN TAB.EXE_FileVersion like '%[ ]%' THEN REPLACE(TAB.EXE_FileVersion,' ','')
	--WHEN TAB.EXE_FileVersion like '%[,]%' THEN REPLACE(TAB.EXE_FileVersion,',','.')
	WHEN TAB.EXE_FileVersion like '%[ ]%' THEN SUBSTRING(TAB.EXE_FileVersion,0, LEN(TAB.EXE_FileVersion) - LEN(SUBSTRING(TAB.EXE_FileVersion,0,LEN(TAB.EXE_FileVersion) - CHARINDEX(' ',TAB.EXE_FileVersion))))
	WHEN TAB.EXE_FileVersion = 'sonicmf.exe' THEN NULL
	WHEN TAB.EXE_FileVersion like '%A%' THEN REPLACE(TAB.EXE_FileVersion,'A','')
	WHEN TAB.EXE_FileVersion like 'x%' THEN NULL
	WHEN TAB.EXE_FileVersion like '%c' THEN REPLACE(TAB.EXE_FileVersion,'c','')
	WHEN TAB.EXE_FileVersion like '%g' THEN REPLACE(TAB.EXE_FileVersion,'g','')
	WHEN TAB.EXE_FileVersion like '%WUG%' THEN REPLACE(TAB.EXE_FileVersion,'WUG','')
	
	
	ELSE TAB.EXE_FileVersion
	END AS EXE_FileVersion

 
 FROM  TAB
 
 WHERE TAB.OS_Name like '%Server%' -- UNIQUEMENT LES OS SERVEURS

"),


[Parameter(Mandatory=$true,HelpMessage="Dossier d'export du fichier CSV")]
[string]$ExportFolder,

[Parameter(Mandatory=$true,HelpMessage="Chemin du dossier où creer le log du script")] 
[string]$LogFolder

)


# SCRIPT NAME
$ScriptName = "SCCM_Roles_And_Apps.ps1"


# LogName = ScriptName without extension
$Log = $ScriptName.Split('.')[0]


### FUNCTIONS

# Function Write-Log



function Write-Log 
{ 
    <# 
    .SYNOPSIS 
        This function creates or appends a line to a log file. 
 
    .PARAMETER  Message 
        The message parameter is the log message you'd like to record to the log file. 
 
    .EXAMPLE 
        PS C:\> Write-Log -Message 'Value1' 
        This example shows how to call the Write-Log function with named parameters. 
    #> 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory)] 
        [string]$Message,
        [Parameter(Mandatory)] 
        [string]$LogPath, 
        [Parameter(Mandatory)] 
        [string]$LogName
        
    ) 
     
    try 
    { 
        $DateTime = Get-Date -Format ‘MM-dd-yy HH:mm:ss’ 
        Add-Content -Value "$DateTime # $Message" -Path "$LogPath\$LogName.log" 
    } 
    catch 
    { 
        Write-Error $_.Exception.Message 
    } 
} 


Function GetSQLData {

<# 
    .SYNOPSIS 
        This function query SQL Database and get Data 
 
    .PARAMETER  
        SQLInstance: Instance SQL.
        SQLDB: Base SQL.
        SQLQuery: Requete SQL.

 
    .EXAMPLE 
        GetSQLData -SQLInstance "MyInstance" -SQLDB "MyDB" -SQLQuery "Select * from MyView"
    #> 


[CmdletBinding()] 
    Param( 
        [Parameter(Mandatory=$false)] 
        [string[]] 
        $SQLInstance,
        [Parameter(Mandatory=$false)] 
        [string[]] 
        $SQLDB,
        [Parameter(Mandatory=$false)] 
        [string[]] 
        $SQLQuery
        
        )

$connectionString = "Data Source=$SQLInstance;"+"Integrated Security=SSPI;"+"Initial Catalog=$SQLDB"

$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$command = new-object system.data.sqlclient.sqlcommand($SQLQuery,$connection)
$connection.Open()

$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataSet) | Out-Null

$connection.Close()
$dataSet.Tables

}






# EXECUTE Query ($SQLQuery)
    Write-Log -Message "Execution of GetSQLData on $SQLDB" -LogPath $LogFolder -LogName $Log
    $Result = 
    Try {
        GetSQLData -SQLInstance $SQLInstance -SQLDB $SQLDB -SQLQuery $SQLQuery
        }
    Catch
        {
        $Message = "ERROR DURING EXECUTION OF QUERY"
        Write-Host -F Red $Message
        Write-Log -Message "$Message - $($Error[0].Exception)" -LogPath $LogFolder -LogName $Log
        Exit 1
        }


########################################
# SOUS-REGROUPEMENTS
########################################


# All IIS
$AllIIS = $Result.rows.Where({$_.ServiceName -eq 'W3SVC' -and $_.Service_StartMode -eq 'Auto'}) | select Machine_Name | group Machine_Name | select name -ExpandProperty name

# All SQLDBEngine
$AllSQLDBEngine = $Result.rows.Where({$_.AddRemove_Name -like 'SQL Server*' -and $_.AddRemove_Name -like  '*Database Engine Services'}) | select Machine_Name | group Machine_Name | select name -ExpandProperty name

# All SQL Reporting Services
$AllSQLRS = $Result.rows.Where({$_.AddRemove_Name -like 'SQL Server*'`
    -and $_.AddRemove_Name -like  '*Reporting Services'`
    -and $_.AddRemove_Name -notlike '*Management Studio*'`
    -and $_.AddRemove_Name -notlike '*Data Tools*'`
        
    }) | select Machine_Name | group Machine_Name | select name -ExpandProperty name



# All Citrix Servers
$AllCitrixSrv = $Result.rows.Where({$_.ServiceName -eq 'BrokerAgent' -or $_.ServiceName -eq 'CitrixStorefront' }) | select Machine_Name | group Machine_Name | select name -ExpandProperty name


# All Apache Tomcat Servers
$AllTomcatSrv = $Result.rows.Where({$_.AddRemove_Name -like 'Apache Tomcat*'}) | select Machine_Name | group Machine_Name | select name -ExpandProperty name




# EXPORTS TO TXT FILES

$AllIIS | sort |  Out-File -FilePath "$ExportFolder\All_IIS.txt" -Force

$AllSQLDBEngine | sort |  Out-File -FilePath "$ExportFolder\AllSQLDBEngine.txt" -Force

$AllSQLRS | sort |  Out-File -FilePath "$ExportFolder\AllSQLRS.txt" -Force

$AllCitrixSrv | sort |  Out-File -FilePath "$ExportFolder\AllCitrixSrv.txt" -Force




# DISPLAY SUCCESS
$Message = "--- EXECUTION OK ---"
Write-Host -F Green $Message
Write-Log -Message $Message -LogPath $LogFolder -LogName $Log


 

MECM : Vérifier et corriger l'état du contenu sur un point de distribution

Scénario : 

Nous avons constaté qu'un package est bloqué à 0% en téléchargement dans le centre logiciel.

Depuis la console MECM, nous avons vérifié les boundaries, tout est correctement configuré.

Ensuite nous avons vérifié l'état de distribution du package sur le point de distribution, le package est affiché distribué avec succès.

Pour s'assurer de la bonne distribution du package, nous nous sommes connecté au serveur avec le rôle point de distribution et nous avons constaté qu'il manque le fichier avec le PackageID.ini sous SCCMContentLib\PkgLib.

Nous avons décidé de vérifier l'état de distribution avec l'outil Content Library Explorer :

--> L'état de notre package est PENDING, c'est à dire sa distribution n'a pas pu aboutir.

--> Ce phénomène peut arriver dans le cas où le package a été supprimé mais n'a pas été correctement nettoyé du WMI du point de distribution, mais dans notre cas le package existe toujours et n'a pas été supprimé.

Après vérification, le chemin des sources du package a été modifié sur le serveur qui les héberge. Cette modification a été la cause de l'état PENDING de notre package.

Résolution :

Lorsqu'on change le chemin des sources d'un package MECM (exemple : de "D:\sources\VLC" à "D:\sources\VLC\v3.1"), il faut aussi mettre à jour le chemin vers le contenu dans l'onglet "Content" (cas d'une application) ou "Data Source" (cas d'un package) du package depuis la console.

Est-ce suffisant ? La réponse est NON !

Il faut également lancer l'action Update Content (depuis l'onglet Deployment Types) si c'est une application :

Ou l'action Update Distribution Points si c'est un package :

MECM : Réinitialisation du mot de passe du compte de service Network Access Account

MECM utilise plusieurs comptes de service, en suivant les bonnes pratiques, ci-dessous les principaux comptes de service à créer pour être utilisés par ConfigMgr :

  • Administration account
  • Client Push account
  • Network Access account
  • SQL Reporting account
  • SQL Engine account
  • SQL Agent account
  • Computer Domain Join account

La réinitialisation du mot de passe de tous ces comptes de service ne pose aucun problème, sauf celui du compte Network Access.

Le changement du mot de passe du compte Network Access, provoque le verrouillage en boucle de ce dernier.

Pour éviter les verrouillages de compte, ne modifiez pas le mot de passe d'un compte Network Access existant. Au lieu de cela, créez un nouveau compte et configurez le dans Configuration Manager.

Lorsque suffisamment de temps s'est écoulé pour que tous les clients aient reçu les détails du nouveau compte, supprimez l'ancien compte des dossiers partagés du réseau et supprimez le.

Pour ajouter un nouveau compte Network Access :

Sources:

Accounts used - Configuration Manager | Microsoft Learn

MECM : Paramètres de langue dans SUP pour Windows 11 Servicing (déploiement Feature Updates)

Contrairement aux versions précédentes de Windows, les Feature Updates de Windows 11 dans MECM Servicing nécessitent de définir toutes les langues nécessaires dans le point de mise à jour logicielle. Sinon, ils seront synchronisés mais pas téléchargés.

Configuration classique pour Windows 10

Prenant un exemple où on souhaite télécharger les Feature updates Windows 10 en Anglais, Français, Italien, Allemand et Espagnol :

--> Uniquement deux langues cochées dans la configuration SUP, mais les Feature Updates Windows 10 peuvent être synchronisés et téléchargés en plusieurs langues.

Configuration pour Windows 11

Le Windows Servicing dans MECM ne télécharge les maj d'upgrade Windows 11 que si les langues sont configurées dans SUP.

Prenant le même exemple ci-dessus (Anglais, Français, Italien, Allemand et Espagnol) :

Si on ne coche que Français et Anglais, les Feature Updates Windows 11 seront synchronisés en plusieurs langues mais ne peuvent être téléchargés que en langue française et anglaise.

MECM (SCCM) : Bonnes pratiques pour Windows 10 Servicing Upgrades (mises à jour des fonctionnalités)

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, il y a quelques bonne pratiques à appliquer pour optimiser le process.

Ci-dessous 4 bonnes pratiques :

1. Définissez les paramètres ci-dessous sur la règle du plan de maintenance pour vous assurer de ne pas avoir de groupe de mise à jour logicielle vide après une synchronisation mensuelle des mises à jour SCCM, où les mises à jour des fonctionnalités sont remplacées (exemple de migration vers Windows 10 1909)

2. Augmentez la durée d'exécution maximale des mises à jour des fonctionnalités de Windows 10, de 120 minutes (valeur par défaut) à 600 minutes pour éviter la corruption de la migration (pour les appareils lents)

3. Définissez un plan de gestion de l'alimentation personnalisé sur les collections d'appareils cibles de migration pour désactiver le mode veille et l'arrêt du disque lorsque l'ordinateur n'est pas sur batterie

  • Assurez-vous que la gestion de l'alimentation est activée dans les paramètres du client

  • Sur une collection contenant tous les ordinateurs cibles pour la migration, définissez un plan personnalisé (ConfigMgr) pour les plans Peak et Non-Peak avec les modifications suivantes :

4. Modifiez les paramètres du client dans l'onglet des mises à jour logicielles comme suit :

  • Calendrier d'analyse des mises à jour logicielles > A lieu toutes les 12h (valeur par défaut : 24h)
  • Planifier la réévaluation du déploiement > A lieu toutes les 12h (valeur par défaut : 24h)
  • Dès que l'échéance d'un déploiement de mise à jour logicielle est atteinte, installer tous les autres déploiement de mise à jour logicielle avec une échéance pendant une période de temps spécifiée > Non (valeur par défaut : Oui)
  • Spécifier la priorité du thread pour les mises à jour des fonctionnalisés > Normal (valeur par défaut : Non configuré)

SCCM - SQL Query - 'Last Enforcement State' pour tout les déploiements/computers.

La requete SQL ci-dessous liste l'état d'application (Enforcement) pour toutes les machines et les deploiements correspondant.

 

/*** SCCM - QUERY TO DISPLAY ALL COMPUTERS 'LAST ENFORCEMENT STATE' FOR ALL DEPLOYMENTS  ***/


DECLARE @StartDate DATETIME, @EndDate DATETIME
	
-- Since 12 months
SET @StartDate = DATEADD(mm, -12,GETDATE())
SET @EndDate = GETDATE() 


SELECT

vrs.Name0,

CASE vrs.Active0
	WHEN 0 THEN 'NO'
	WHEN 1 THEN 'YES'
	END AS Client_Active,

a.AssignmentName as DeploymentName,
a.StartTime as Deploy_Available,
a.EnforcementDeadline as Deploy_Deadline,
sn.StateName as LastEnforcementState,
wsus.LastErrorCode as 'LasErrorCode'


FROM v_CIAssignment a
JOIN v_AssignmentState_Combined assc on a.AssignmentID=assc.AssignmentID
JOIN v_StateNames sn on assc.StateType = sn.TopicType and sn.StateID=isnull(assc.StateID,0)
JOIN v_R_System vrs on vrs.ResourceID = assc.ResourceID
JOIN v_GS_WORKSTATION_STATUS wks on wks.ResourceID = assc.ResourceID
JOIN v_UpdateScanStatus wsus on wsus.ResourceID = assc.ResourceID


AND CreationTime BETWEEN @StartDate AND @EndDate -- IN A SPECIFIC TIME WINDOW FOR THE DEPLOYMENT CREATION TIME

ORDER BY Deploy_Available DESC

 

 

Office : Erreur de mise à niveau du client Office 2016 vers la version M365 2008 en utilisant le centre logiciel MECM

Scenario:

L'utilisateur avait Office 2016 32 bits installé et souhaite faire une mise à niveau vers le client M365 v2008 (semi-annual channel).

Problème:

Lors de la mise à niveau, l'erreur 0x80077562 (-2146994846) s'affiche dans le centre logiciel MECM --> Tous les produits office ont cessé de fonctionner et Office 2016 n'a pas été supprimé des programmes.

Lorsque vous essayez de désinstaller manuellement l'ancienne version d'Office 2016, cette erreur s'affiche :

"La langue de ce package d'installation n'est pas prise en charge par le système"

Explication:

Cette erreur est parfois causée par l'échec des précédentes tentatives d'installation/désinstallation du produit Office.

Solution:

1. Réinstallez Office 2016 32 bits à l'aide des sources d'installation d'Office

2. Réessayez l'installation d'Office 365 à partir du centre logiciel

MECM (SCCM) : Windows 10 Servicing Upgrade, la fameuse erreur "L'opération n'a pas été effectuée car il n'y a pas d'utilisateur interactif connecté"

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, il y a une erreur connue qui bloque la migration et bloque même le Retry.

L'erreur est la suivante : "L'opération n'a pas été effectuée car il n'y a pas d'utilisateur interactif connecté"

Cette erreur aura lieu quand il y a vraiment besoin d'une intervention utilisateur et que le mécanisme de mise à niveau Windows 10 en arrière plan ne peut pas remédier au problème automatiquement, généralement c'est l'un de ces deux cas :

1. Il y a un antivirus qui bloque la migration ou tout autre outil qui doit être mis à jour ou désinstallé

On peut détecter ce genre de problème en se connectant sur la machine, ouvrir le chemin suivant C:\$WINDOWS~BT\Sources\Panther, puis ouvrir le fichier CompatData*.xml le plus récemment modifié (c'est le fichier qui contient les données de scan de compatibilité)

Dans la capture ci-dessus, c'est l'outil de sécurité Check Point Endpoint Security qui a bloqué la migration Windows 10.

Vous pouvez utiliser le lien Microsoft qui est proposé dans le fichier xml pour trouver une solution.

2. Reset manuel de la migration

Pas mal de fois, le fichier de compatibilité CompatData*.xml ne contient aucun bloqueur dur de la migration et pourtant elle est bloquée.

Dans ce cas, il faut manuellement faire un reset de la migration par la suppression du dossier "$WINDOWS~BT" et le nettoyage du contenu du dossier "C:\Windows\SoftwareDistribution\Download".

Une fois ces actions sont faites, la migration fait un Retry automatiquement.

 

Remarque:

"$WINDOWS~BT" est un dossier caché

SCCM - SQL Query - Inventaire Software, Executables et AddRemove Programs

La requête ci-dessous fait un 'UNION' entre trois requêtes sur les vues [v_GS_INSTALLED_SOFTWARE_CATEGORIZED], [v_GS_INSTALLED_EXECUTABLE] et [v_ADD_REMOVE_PROGRAMS] pour obtenir un inventaire logiciel un peu plus "avancé".

N.B: Modifiez la variable @CollectionID si besoin pour réduire le scope des machines concernées, et éviter un nombre conséquent de ligne renvoyées.

 

/* --- SOFTWARES, EXECUTABLES, AND ADD-REMOVE PROGRAMS ENTRIES INVENTORY ---  
 NB: UNION ENTRE LES VUES:
	 [v_GS_INSTALLED_SOFTWARE_CATEGORIZED] 
	 [v_GS_INSTALLED_EXECUTABLE]
	 [v_ADD_REMOVE_PROGRAMS]
	 
	       
 NB: DES COLONNES SONT CREES ET POSITIONNEE A NULL POUR POUVOIR EFFECTUER LE UNION. (Meme nombre de colonnes) 

v_GS_INSTALLED_SOFTWARE_CATEGORIZED
Répertorie des informations sur les applications logicielles installées sur Configuration Manager clients trouvés via Asset Intelligence. 
Cette vue contient les informations contenues dans le v_GS_INSTALLED_SOFTWARE afficher et joint plusieurs autres tables pour fournir des détails supplémentaires sur les logiciels installés.

v_GS_INSTALLED_EXECUTABLE
Répertorie des informations sur les fichiers exécutables de l’application logicielle installée sur Configuration Manager clients trouvés via Asset Intelligence.

[v_ADD_REMOVE_PROGRAMS]
Combination of 32 and 64 bit programs data in 'Add Remove Programs'
*/



DECLARE @CollectionID as Varchar(8)
SET @CollectionID = 'SMS00001' --Specify the collection ID


SELECT  DISTINCT 

TAB.ResourceID
,TAB.ProductCode
,TAB.[Machine Name]
,TAB.OS_Name
,TAB.Publisher0
,TAB.NormalizedPublisher
,TAB.ExecutableName
,TAB.ProductName
,TAB.AddRemove_Name
,TAB.NormalizedName
,TAB.FamilyName
,TAB.CategoryName
,TAB.InstallDate
,TAB.Soft_Autostart
,TAB.EXE_FilePath
,TAB.EXE_Description
,TAB.ProductVersion
,TAB.EXE_FileVersion



 FROM (


SELECT 
SYST.ResourceID,
UPPER(SOFT.ProductCode0) as ProductCode,
SYST.Name0 as 'Machine Name',

-- OS Info --
OS.Caption0 as OS_Name,

-- SOFT INFO --
SOFT.Publisher0,
SOFT.NormalizedPublisher,
NULL as ExecutableName,
SOFT.ProductName0 as ProductName,
NULL as AddRemove_Name,
SOFT.NormalizedName,
SOFT.FamilyName,
SOFT.CategoryName,
SOFT.ProductVersion0 as ProductVersion,


SOFT.InstallDate0 as InstallDate,


CASE 
	WHEN AUTOSTART_SOFT.Product0 IS NULL THEN 'NO'
	ELSE 'YES'
	END as Soft_Autostart,

NULL as EXE_FilePath,
NULL as EXE_Description,
NULL as EXE_FileVersion


FROM [dbo].[v_GS_INSTALLED_SOFTWARE_CATEGORIZED] SOFT
FULL JOIN v_R_System SYST on SYST.ResourceID = SOFT.ResourceID
FULL JOIN [dbo].[v_GS_OPERATING_SYSTEM] OS on OS.ResourceID = SYST.ResourceID
FULL JOIN [dbo].[v_GS_AUTOSTART_SOFTWARE] AUTOSTART_SOFT on AUTOSTART_SOFT.Product0 = SOFT.ProductName0   -- TO MAKE RELATION WITH AUTO-START SOFTWARE
FULL JOIN v_FullCollectionMembership on (v_FullCollectionMembership.ResourceID = SYST.ResourceID)

WHERE v_FullCollectionMembership.CollectionID = @CollectionID


  
UNION 
 

SELECT 
  

SYST.ResourceID,
UPPER(EXE.ProductCode0) as ProductCode,
SYST.Name0 as 'Machine Name'

-- OS Info --
,OS.Caption0 as OS_Name

,EXE.Publisher0
,NULL as NormalizedPublisher
,EXE.ExecutableName0 as ExecutableName
,EXE.Product0 as ProductName
,NULL as AddRemove_Name
,NULL as NormalizedName
,NULL as FamilyName
,NULL as CategoryName 
,EXE.ProductVersion0 AS ProductVersion
,NULL as InstallDate
,NULL as Soft_Autostart

,EXE.InstalledFilePath0 as EXE_FilePath
,EXE.Description0 as EXE_Description
,EXE.FileVersion0 AS EXE_FileVersion


FROM [dbo].[v_GS_INSTALLED_EXECUTABLE] EXE
  
  FULL JOIN v_R_System SYST on SYST.ResourceID = EXE.ResourceID
  FULL JOIN [dbo].[v_GS_OPERATING_SYSTEM] OS on OS.ResourceID = SYST.ResourceID
  FULL JOIN v_FullCollectionMembership on (v_FullCollectionMembership.ResourceID = SYST.ResourceID)
 
 WHERE v_FullCollectionMembership.CollectionID = @CollectionID
 
  
  
UNION


SELECT
ARP.ResourceID
,UPPER(ARP.ProdID0) as ProductCode
,SYST.Name0 as 'Machine Name'
-- OS Info --
,OS.Caption0 as OS_Name
,ARP.Publisher0
,NULL as NormalizedPublisher
,NULL as ProductName
,NULL as ExecutableName
,ARP.DisplayName0 as AddRemove_Name
,NULL as NormalizedName
,NULL as FamilyName
,NULL as CategoryName 
,ARP.Version0 AS ProductVersion 

,CASE
WHEN ISDATE(ARP.InstallDate0) <> 0 THEN CONVERT(date,ARP.InstallDate0)
WHEN ISDATE(ARP.InstallDate0) = 0 THEN NULL
END AS InstallDate

,NULL as Soft_Autostart
,NULL as EXE_FilePath
,NULL as EXE_Description
,NULL as EXE_FileVersion

FROM [dbo].[v_ADD_REMOVE_PROGRAMS] ARP
FULL JOIN v_R_System SYST on SYST.ResourceID = ARP.ResourceID  
FULL JOIN v_FullCollectionMembership on (v_FullCollectionMembership.ResourceID = SYST.ResourceID)
INNER JOIN [dbo].[v_GS_OPERATING_SYSTEM] OS on OS.ResourceID = SYST.ResourceID  

WHERE v_FullCollectionMembership.CollectionID = @CollectionID 
  
  ) AS TAB

 

 

 

 

 

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