If you wish to export Yammer reports, yes its now Viva Engage but that name is awful and its still Yammer from a website point of view, despite the new logo that looks like headless people giving each other a hug......
If you need to export Yammer reports then you need to have privileged roles to complete the action which you do not want to be dishing out to normal users so it ends up being a valid user with access that does this operation, if you have a monthly report this can become tedious, so I have created a script to complete this action for me, it pulls all the reports with Graph API (and the relevant delegated API permission) then sends an email to the intended users.
This is what it looks like when running:
Pre-Flight : Prerequisites
Script : Install-Requirements.ps1
#Required for Proxy only
#$proxy = 'squid.bear.local:3129'
#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
#[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($proxy)
#[system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
# First, set up PowerShell Gallery and required modules
function Initialize-PowerShellModules {
Write-Host "Setting up PowerShell Gallery and required modules..." -ForegroundColor Yellow
# Set TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Configure default proxy settings if needed
Write-Host "Configuring proxy settings..." -ForegroundColor Yellow
[System.Net.WebRequest]::DefaultWebProxy = [System.Net.WebRequest]::GetSystemWebProxy()
[System.Net.WebRequest]::DefaultWebProxy.Credentials =
[System.Net.CredentialCache]::DefaultNetworkCredentials
# Force register PowerShell Gallery
Write-Host "Forcing PowerShell Gallery registration..." -ForegroundColor Yellow
try {
$galleryParams = @{
Name = 'PSGallery'
SourceLocation = 'https://www.powershellgallery.com/api/v2'
PublishLocation = 'https://www.powershellgallery.com/api/v2/package'
InstallationPolicy = 'Trusted'
}
# Remove any existing PSGallery registration
Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue |
Unregister-PSRepository -ErrorAction SilentlyContinue
# Register PSGallery with explicit parameters
Register-PSRepository @galleryParams
# Verify registration
$gallery = Get-PSRepository -Name PSGallery -ErrorAction Stop
Write-Host "PSGallery successfully registered: $($gallery.SourceLocation)" -ForegroundColor Green
}
catch {
Write-Host "Error registering PSGallery: $_" -ForegroundColor Red
# Fallback to Register-PSRepository -Default
Write-Host "Attempting fallback registration..." -ForegroundColor Yellow
Register-PSRepository -Default -Verbose
}
# Install/Import PackageManagement and PowerShellGet first
Write-Host "Updating core PowerShell package management..." -ForegroundColor Yellow
$bootstrapModules = @('PackageManagement', 'PowerShellGet')
foreach ($module in $bootstrapModules) {
try {
if (!(Get-Module -Name $module -ListAvailable)) {
Write-Host "Installing $module..." -ForegroundColor Yellow
Install-Module -Name $module -Force -AllowClobber -Scope CurrentUser -Verbose
}
Import-Module $module -Force
}
catch {
Write-Host "Warning: Could not update $module. Continuing with existing version." -ForegroundColor Yellow
}
}
# Install/Import NuGet if needed
if (!(Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) {
Write-Host "Installing NuGet provider..." -ForegroundColor Yellow
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser -Confirm:$false
}
# Required modules
$modules = @(
@{
Name = "Microsoft.Graph.Authentication"
MinimumVersion = "1.19.0"
},
@{
Name = "Microsoft.Graph.Reports"
MinimumVersion = "1.19.0"
}
)
foreach ($module in $modules) {
Write-Host "Processing module: $($module.Name)..." -ForegroundColor Yellow
try {
# Check if module is installed
$installedModule = Get-Module -ListAvailable -Name $module.Name |
Where-Object { $_.Version -ge $module.MinimumVersion }
if (-not $installedModule) {
Write-Host "Installing $($module.Name)..." -ForegroundColor Yellow
# Try installation with verbose output
$installParams = @{
Name = $module.Name
MinimumVersion = $module.MinimumVersion
Force = $true
AllowClobber = $true
Scope = 'CurrentUser'
Verbose = $true
}
Install-Module @installParams
# Verify installation
$verifyModule = Get-Module -ListAvailable -Name $module.Name |
Where-Object { $_.Version -ge $module.MinimumVersion }
if (-not $verifyModule) {
throw "Module installation verification failed"
}
}
else {
Write-Host "$($module.Name) version $($installedModule.Version) is already installed" -ForegroundColor Green
}
# Import the module
Import-Module -Name $module.Name -MinimumVersion $module.MinimumVersion -Force
# Verify import
if (Get-Module -Name $module.Name) {
Write-Host "$($module.Name) imported successfully" -ForegroundColor Green
}
else {
throw "Module import verification failed"
}
}
catch {
Write-Host "Error processing $($module.Name): $_" -ForegroundColor Red
Write-Host "Exception details: $($_.Exception.Message)" -ForegroundColor Red
throw
}
}
}
# Run the initialization
try
Initialize-PowerShellModules
Write-Host "Module setup completed successfully" -ForegroundColor Green
}
catch {
Write-Host "Failed to set up modules: $_" -ForegroundColor Red
Write-Host "Exception details: $($_.Exception.Message)" -ForegroundColor Red
# Additional troubleshooting information
Write-Host "`nTroubleshooting information:" -ForegroundColor Yellow
Write-Host "PowerShell Version: $($PSVersionTable.PSVersion)" -ForegroundColor Yellow
Write-Host "OS: $([System.Environment]::OSVersion.VersionString)" -ForegroundColor Yellow
Write-Host "PSGallery Status:" -ForegroundColor Yellow
Get-PSRepository | Format-Table -AutoSize
# Network connectivity test
Write-Host "`nTesting network connectivity:" -ForegroundColor Yellow
Test-NetConnection -ComputerName "www.powershellgallery.com" -Port 443 |
Select-Object ComputerName, TcpTestSucceeded, PingSucceeded
exit 1
}
This will install the required modules with some testing then we can continue on to the main script that does the Graph API connection and extraction, however first we need to setup an application registration (which is OAuth) to handle the secret and API permissions - this is required for the script to work without getting the error "Forbidden".
Pre-Flight : Application Registration
This section will guide you though the application registration which is required for the script, so first visit the Azure Portal website here
Then when here you will need to navigate to Entra ID as below:
Then from here you need App Registrations as below:
Then we need New Registration:
Then give it a name and ensure its is only for a single tenant then click Register:
Then ensure you have client secrets selected and choose New client secret:
Give it a name and a lifetime (I like 12 months) then click the add:
You will then see the client secret and value as below:
Note : You will only see the value once when you navigate away from this screen and back the value will no longer be visible!
If you need an example of what refreshing the pages does see this example below:
Now we need to go to Manage then API Permissions:
Then you need to add an API permission and choose Microsoft Graph as below:
Then you need application permissions as below:
We now need to add these permissions:
So first search for Report.Read.All in the search box, but a tick in the box and then choose Add Permissions:
The next permission is a Delegated permission, so from Graph API you need the other option as below:
Then you cannot search for User.Read lots of permissions use this, so find the User section choose it from that section as below, tick the box then Add Permission:
You should now see your permissions in API permissions as below, however notice that "Admin Consent" has not been granted (red box) so we need to fix this for the correct API permissions, so click the Grant button (green box):
Then we will be asked to confirm the action and here we need to say yes:
You can confirm this was worked when you see the two green ticks next to the permissions:
That concludes the setup of the application and the API permissions, secrets and delegation, however from this we also need to have the following details handy:
Tenant ID
Application ID
I have covered the secret earlier, but for the other two data points from your App Registration click the overview button, that will tell you this information outlined in the boxes below:
Running the export
Script : YammerReport.ps1