PI Services

Le blog des collaborateurs de PI Services

Sharepoint Online : Script de Restauration d'éléments dans la corbeille.

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

 

Sharepoint Online : Comment faire un export des éléments dans la corbeille d’un site.

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 

 

Powershell : Credentials Test Function

 

Une petite fonction Powershell pour vous permettre de vérifier des identifiants.

Function Test-Credential {
    PARAM (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
        [STRING]$User,
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1)]
        [STRING]$Pass
        )
    Process {
        # Test Credentials
        Add-Type -AssemblyName system.DirectoryServices.AccountManagement
        $DirectoryService = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('domain')
        $Credentials = $DirectoryService.ValidateCredentials($User,$Pass)

        # Return
        If ($Credentials -eq $true) {
            Write-Host "Credentials are correct" -ForegroundColor Green
            }
        Else {
            Write-Host "Credentials are no good" -ForegroundColor Red
            }
        }
    }

 

WSUS Server : Connection Error

Vous venez de déployer un serveur WSUS, finir sa configuration et rattacher les premières machine à se dernier; mais lorsque vous vous rexonnectez sur le serveur afin d'exécuter la console "Windows Server Update Services" vous avez le droit au message d'erreur suivant :

La cause :

Bien souvent cette erreur est lié à IIS, je vous invite donc à exécuter "Internet Information Services (IIS) Manager" puis déroulez le serveur et sélectionnez "Application Pool", ici vous pourrez constater que le "WsusPool" est arrêté.

La solution :

Sélectionnez le et faite "Advanced Settings..." dans le volet de droite, sélectionnez le "Start Mode" pour le passer de "OnDemand" à "AlwaysRunning" puis validez en faisant "OK".

Démarrez le "WsusPool", puis vous pourrez fermer la console IIS.

NB : Tant que le serveur WSUS n'aura pas redémarrez la configuration du IIS ne sera pas effective (vous devrez relancez le "WsusPool" Manuellement à chaque nouvelle connexion au serveur).

Retournez dans la console "Windows Server Update Services" et faites "Reset Server Node"

Enjoy

 

Sharepoint Online : Problème d'accès

Il m'est arrivé il y a peu de temps un cas un peu spécifique, quelqu'un qui bénéficiait de droit "Full Control" sur Sharepoint online se voyait gratfié d'un "Access Denied" à chaque tentative de connexion sur l'url de son site et ceux même en cliquant sur le lien envoyé par Sharepoint lorsqu'on lui attribuait les droits.

La Cause:

En fait cette personne avait bénéficié de droits divers et variés (en accès direct, via l'appartenance à des groupes, via les demandes, Full Control, Edit, Read Only, Limited Access...) car personne parmis les gestionnaires Shrepoint ne parvenait à lui donner les droits.

Par conséquent nous sommes tombé dans un conflit de droits d'accès qui n'a pu être résolu de manière graphique, mais via Powershell.

 

La Solution: 

Afin de solder le problème il a fallu passer par Powershell et supprimer les dépendances de ce compte via la suppression du compte de la "UserInfo List".

Pour ce faire nous avons utilisé les commandes ci-dessous (Attention le module Sharepoint Online pour Powershell est nécessaire):

# Connexion à Sharepoint Online
Connect-SPOService -Url https://monnorganisation.sharepoint.com -Credential "adm-maade@monorganisation.com"

# Vérification des groupes d'appartenance pour mon Utilisateur
$AllUsers = Get-SPOUser -Site https://monnorganisation.sharepoint.com/sites/Toto
$FilterMonUser = $AllUsers.where({$_.loginname -eq "tartanpion@globule.net"})

# Afficher les groupes de mon Utilisateur
$FilterMonUser.groups

# Suppression de mon utilisateur de la UserInfo List
Remove-SPOUser -Site "https://monnorganisation.sharepoint.com/sites/Toto" -LoginName "tartanpion@globule.net"

 

Une fois la commande terminée, j'ai pu réaffecter les bons droits au travers du bon groupe dans l'interface du site Sharepoint.

Info supplémentaires:

https://docs.microsoft.com/en-us/sharepoint/remove-users

 

Hyper-V : Créer un disque de différenciation (Partie 3)

Après avoir définit les paramètres et le déploiement de l'OS de notre VM de référence dans les articles précédents, nous allons pouvoir créer un disque de différentiation.

1. Créer un disque de différentiation.

Dans la console Hyper-V Manager faites « New », « Virtual Hard Disk »

Choisissez le format du Disque (dans notre cas VHDX) et faites « Next »

Pour le type de disque nous choisirons donc « Differencing » avant de faire « Next »

Donnez un nom au disque et sélectionnez le répertoire dans lequel il sera créé

Dans configure Disk sélectionnez « Browse… »

Indiquez ensuite l’emplacement du disque de référence créé dans les étapes précédentes (Partie 1) et faites « Next »

Lisez le résumé puis faites « Finish »

 

Maintenant que le disuqe est créé nous pouvons passer à la VM.

2. Création d'une VM.

Sélectionnez le serveur Hyper-V et faites un clic droit « New » puis « Virtual Machine ».

Dans la fenêtre « Before you Begin » faites « Next »

Dans la fenêtre « Specify Name and Location » donnez un nom à votre VM (pour moi VM01) et sélectionnez « Store the virtual machine in a different location » et cliquez sur « Browse… »

Sélectionnez le répertoire dans lequel seront stocké les éléments de configuration de la VM puis « Select Folder »

Faites « Next »

Sélectionnez le type de génération de la VM (dans mon cas une VM de génération 2) et faites « Next »

Assignez une quantité de RAM à la VM et faites « Next ».

Il n’est pas obligatoire d’assigner une carte réseau pour la machine de référence, faites « Next ».

Dans la configuration du disque dur choisissez « Use an existing virtual hard disk », puis faites « Browse... ».

Sélectionnez le disque créé pour la VM dans l'étape 1 puis « Open »

 

Faites « Next »

Faites « Finish »

 

 

 

Hyper-V : Créer un disque de différenciation (Partie 2)

Après avoir définit les paramètres de la VM dans le précédent article nous allons maintenant déployer l'OS de notre VM de référence.

1. Déploiement de l'OS.

1- Connectez vous à la VM et démarrez-la.

2- Sélectionnez la langue d’installation du système d’exploitation (s’il vous plait Anglais cela évitera les problèmes plus tard) puis le fuseau horaire et la langue du clavier (cette fois-ci vous pouvez mettre Français) et enfin faites « Next »

3- Cliquez sur « Install Now »

4- Sélectionnez la version de l’OS à installer (Core ou Graphique) et la version de licence correspondante (Standard ou Datacenter) et faites « Next »

5- Cochez « I accept the license term agreement” et faites « Next »

6- Sélectionnez « Custom: Install Windows only (advanced) »

7- Sélectionnez le disque et faites « Next »

8- Attendez la fin de l’installation

9- Entrez un mot de passe Admin local

Une fois l’installation terminé, identifiez vous sur la machine (je ne mets pas à jour l’OS car au moment où je rédige ces lignes Windows Server 2019 viens juste de sortir), nous allons donc directement passer au Sysprep.

2. Sysprep

Pour réaliser un sysprep de la machine, allez dans « C:\Windows\System32\Sysprep » et exécuter « Sysprep.exe ».

Lorsque la fenêtre apparait cochez la case « Generalize » et sélectionnez « Shutdown » et faites « OK »

Attendez l’extinction de la VM puis dans « Hyper-V Manager » supprimez la, cette action vous évitera de rallumer la VM par inadvertance (ce qui poserait problème pour toutes les machines configurées à l'aide du disque de référence).

Maintenant que le disque de référence a été créé nous allons pouvoir créer les nouveaux disques et VMs, nous verrons cela dans la partie 3.

Netdom Trust et les OS Français

Un environnement homogène avec des OS installé en Anglais, c'est la vision de notre éditeur préféré (je parle bien sur de Microsoft).

Dans la pratique on a pas toujours l'opportunité d'avoir tous les OS dans la même version et pire encore dans la même langue d'installation.

 

Quel impact ?

Même si pour certain, installer un OS en Français est plus "Confortable / facile d'administration", en terme de "recherche / résolution" d'incident on est quand même nettement moins bien aidé (entre les messages d'erreur qui ne veulent rien dire ou les commandes qui diffèrent, avoir un langage différent de l'anglais peut vous faire perdre quelques heures).

 

Des Exemples :

Prenons un exemple simple l'activation ou la désactivation du "SID Filtering" dans un "Trust" entre deux domaines.

OS Anglais :

Si les OS des serveurs contrôleur de domaine sont en Anglais les commandes sont simples :

Pour désactiver le SID Filtering : 

Netdom trust **TrustingDomainName** /domain:**TrustedDomainName **/quarantine:No  

Nb: Remplacez **TrustingDomainName** par le nom du domaine qui doit approuver l'autre et **TrustedDomainName ** par le nom de domaine qui doit être approuvé.

 

Pour activer le SID Filtering : 

Netdom trust **TrustingDomainName** /domain:**TrustedDomainName **/quarantine:Yes

 Nb: Remplacez **TrustingDomainName** par le nom du domaine qui doit approuver l'autre et **TrustedDomainName ** par le nom de domaine qui doit être approuvé.

 

OS Français :

Lorsque les OS sont en Français il y a une petite subtilité :

Pour désactiver le SID Filtering : 

Netdom trust **TrustingDomainName** /domain:**TrustedDomainName **/quarantine:Non  

Nb: Remplacez **TrustingDomainName** par le nom du domaine qui doit approuver l'autre et **TrustedDomainName ** par le nom de domaine qui doit être approuvé.

 

 

Pour activer le SID Filtering : 

Netdom trust **TrustingDomainName** /domain:**TrustedDomainName **/quarantine:Oui

Nb: Remplacez **TrustingDomainName** par le nom du domaine qui doit approuver l'autre et **TrustedDomainName ** par le nom de domaine qui doit être approuvé.

 

Vous l'avez ?

Et oui la commande est quasi identique puisqu'elle est en Anglais, mais les arguments eux sont en Français et le pire dans tout ça c'est que si vous passez la commande en Anglais avec les arguments en Anglais, l'OS vous dira que la commande s'est terminée avec succès même si ce n'est pas le cas; mais dans la pratique cette dernière aura échouée.

 

Alors de grâce ayez le réflex lors d'une installation serveur de sélectionner un Iso en Anglais et de l'installer en Anglais (rassurez vous pour le clavier et le fuseau horaire le Français est autorisé ^^ ).

Hyper-V : Créer un disque de différenciation (Partie 1)

Comme certain d'entre vous j'en ai eu marre de ne plus avoir de place sur mon disque mais surtout de devoir re-déployer Windows Server à chaque nouvelle VM pour un Lab; voici donc comment créer un disque de différenciation sous Hyper-V.

1. Créer la VM de référence

1- Dans un premier temps, sur votre poste de travail définissez un répertoire dans lequel sera stocké le disque de référence.

Dans mon cas je vais créer le serveur de référence dans mon disque "D" dans un répertoire "Template" et placer son disque dans un sous répertoire "Virtual Hard Disk".

 

2- Ensuite lancez "Hyper-V Manager"

 

3- Puis sélectionnez le serveur Hyper-V et faites un clic droit « New » puis « Virtual Machine ».

Dans la fenêtre « Before you Begin » faites « Next »

4- Dans la fenêtre « Specify Name and Location » donnez un nom à votre machine de référence et sélectionnez « Store the virtual machine in a different location » et cliquez sur « Browse… »

5- Sélectionnez le répertoire dans lequel seront stocké les éléments de configuration de la VM puis « Select Folder »

6- Faites « Next »

7- Sélectionnez le type de génération de la VM (dans mon cas une VM de génération 2) et faites « Next »

8- Assignez une quantité de RAM à la VM (au moins le prérequis système) et faites « Next ».

9- Il n’est pas obligatoire d’assigner une carte réseau pour la machine de référence, faites « Next ».

10- Dans la configuration du disque dur choisissez une taille suffisante pour l’OS (et éventuellement les mises à jour), puis faites « Next ».

11- Sélectionnez l’ISO du Système d’exploitation et faites « Next »

12- Relisez le résumé de la configuration et faites « Finish »

13- Une fois la VM créée dans Hyper-V Manager sélectionnez la et faites « Settings »

14- Naviguez jusque « Checkpoint » et désélectionnez « Enable Checkpoints » puis faites « OK »

La VM est maintenant prête, nous allons donc pouvoir déployer l'image, rendez vous donc dans la partie 2.

 

SCCM : Failed To Run Task Sequence on Hyper-V VM Generation 2

Les messages d'erreur sont parfois frustrant par exemple celui ci-dessous:

En plus de ne pas être des plus explicit, une multitude de cas sont exposé sur internet avec des code erreur divers et variés.

Sans l'accès au log tout devient plus dificile, dans le cas de figure ici présent j'ai voulu déployer une VM de génération 2 sous Hyper-V via un média de boot (clés USB), je pensais que j'allais y passer des heures, mais en fait non 10 minutes tout au plus.

1 - Les causes

Les VM de génération 2 sous Hyper-V, ont par défaut le Secure boot activé.

Le secure boot est une fonctionnalité qui vérifie que le "Boot Loader" est signé par une autorité de confiance de la base UEFI pour empêcher l'exécution non authorisé d'un "Firmware", "OS" ou "Driver"  au démarrage.

Sauf que dans notre cas cela nous empêche de créer la partition pour le "Staging" du WinPe.

2 - Les solutions

désactivez le secure boot.

  1. Lancez Hyper-V management.
  2. Sélectionnez votre VM.
  3. Faites un clic droit "Properties".
  4. Dans "Settings for xxxxxx on xxxxxx" sélectionnez "Security".
  5. décochez la case "Enable Secure boot".
  6. Validez.

 

Créez une partition UEFI.

En cherchant dans les logs on pourrait trouver l'erreur suivante "Unable to find the partition that contains the OS boot loaders. Please ensure the hard disks have been properly partitioned".

  1. Après avoir désativer le sécure boot, démarrez votre VM et faites "F8" durant le démarrage.
  2. Dans l'invite de commande exécutez les commandes suivantes:
    1.  Diskpart (lancez l'utilitaire Diskpart)
    2. List Disk (Listez les disque)
    3. Select disk 0 (sélectionnez le disque 0 qui représente le disque système de la VM)
    4. Clean (permet d'effacer les données)
    5. Convert gpt (permet de convertir le disque)
    6. Create partition efi size=200 (création d'une partition Efi)
    7. Assign letter=s (Assignez un lettre disponible à la partition)
    8. Format quick fs=FAT32 (Formatez la partition)
    9. Create partition msr size=128 (création d'une partition msr)
    10. Create partition primary (création d'une partition Windows)
    11. Assign letter=c (Assignez la lettre C)
    12. Format quick fs=NTFS (Formatez en NTFS)
    13. Exit (quittez Diskpart)
  3. Normalement vous devriez maintenant pouvoir lancer la séquencce de tâche sans encombre.