geretcondit
Goto Top

Powerhsell und Office 365: Alle Nutzer einer Gruppe auslesen die eine Lizenz haben

Hallo meine Lieben mit Administratoren/innen,
folgendes ist mein anliegen.

Wir haben einige Kunden die über uns ihr Office 365 beziehen, darunter auch Firmen die Gerne je nach Standort ihre Rechnungen separat bekommen möchten. Bisher wurde das "von Hand" geregelt, da aber in letzter zeit viele neue Nutzer dazu kamen oder in einen anderen Standort gewechselt sind wollen wir in Zukunft das ganze aus dem Office 365 per Gruppen auslesen in denen die Jeweiligen am Standort befindlichen Nutzer drin sind.


Ich habe hierfür folgendes Script zusammengestellt:

Set-ExecutionPolicy unrestricted

$Customer = "Test Kunde" #CustomerName  
$Username = "readonly@tesst.de"  
$Password = ConvertTo-SecureString 'Password' -AsPlainText -Force  


#Login for Office Tannant
$UserCredential = New-Object System.Management.Automation.PSCredential $Username, $Password
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Connect-MsolService -Credential $UserCredential
Import-Module MSOnline
Import-PSSession $Session


#Get the Data

#Gets the Different Licenses (In Numbers)
function GetLic {
$f = @{expr={$_.AccountSkuID};label="AccountSkuId"},  
 @{expr={$_.ActiveUnits};label="Total"},#Total  
 @{expr={$_.ConsumedUnits};label="Consumed"},#Consumed  
 @{expr={$_.activeunits-$_.consumedunits};label="Unassigned"}#Not Assigend  
Get-MsolAccountSku | sort activeunits -desc | ft $f -auto
}
$AllLicens = GetLic | Out-String

#Reads out all users and shows Licensing Status (Active/Inactive)
function GetUserLic {
Get-MSOLUser -All | select userprincipalname,islicensed,{$_.Licenses.AccountSkuId} | sort islicensed -Desc
}
$UserStatus = GetUserLic | Out-String

#Searches for the ABR groups and Counts the Members
function GetABR { Get-MsolGroup -All | Where-Object {$_.DisplayName -like 'ABR*'} | Foreach {  
    $groupId = $_.ObjectId;
    $groupName = $_.DisplayName;
    $groupLicenses = $_.Licenses | Select -ExpandProperty SkuPartNumber
    $totalCount = 0;
    $licenseAssignedCount = 0;
    $licenseErrorCount = 0;

    Get-MsolGroupMember -All -GroupObjectId $groupId |
    #get full info about each user in the group
    Get-MsolUser -ObjectId {$_.ObjectId} |
    Foreach {
        $user = $_;
        $totalCount++

        #check if any licenses are assigned via this group
        if($user.Licenses | ? {$_.GroupsAssigningLicense -ieq $groupId })
        {
            $licenseAssignedCount++
        }
        #check if user has any licenses that failed to be assigned from this group
        if ($user.IndirectLicenseErrors | ? {$_.ReferencedObjectId -ieq $groupId })
        {
            $licenseErrorCount++
        }     
    }

    #aggregate results for this group
    New-Object Object |
                    Add-Member -NotePropertyName GroupName -NotePropertyValue $groupName -PassThru |
                    Add-Member -NotePropertyName GroupId -NotePropertyValue $groupId -PassThru |
                    Add-Member -NotePropertyName GroupLicenses -NotePropertyValue $groupLicenses -PassThru |
                    Add-Member -NotePropertyName TotalUserCount -NotePropertyValue $totalCount -PassThru |
                    Add-Member -NotePropertyName LicensedUserCount -NotePropertyValue $licenseAssignedCount -PassThru |
                    Add-Member -NotePropertyName LicenseErrorCount -NotePropertyValue $licenseErrorCount -PassThru

    } | Format-Table -AutoSize -Property GroupName,TotalUserCount #Gives out the Totall of Users in the ABR Groups

}
$ABR = GetABR | Out-String  

#Titel
$Title="Lizenz Übersicht: $Customer"  
#Converts the Parts together
$Fragments = $Title + $AllLicens + $ABR + $UserStatus

#Add a footer 
$footer=("Ausgeführt am {0} von {1}\{2}. Created by GeretCondit" -f (Get-Date -displayhint date),$env:userdomain,$env:username)   
$fragments+=$footer 


#Functions to Send the Mail
function Send-Mail($smtpServer,[array]$recp,$subj,$body, $smtpusessl, $smtpport)
{




       $msg = new-object Net.Mail.MailMessage
       $smtp = new-object Net.Mail.SmtpClient($smtpServer, $smtpport)
    
       if ($smtpusessl -eq 1)
       {      
             $smtp.EnableSsl = $true
       }            
       if ($global:smtpuser.Trim() -ne "")  
       {
             $smtp.Credentials = New-Object Net.NetworkCredential ($global:smtpuser.Trim(), $global:smtppassword.Trim())
       }
       
       $msg.From = $global:smtpfrom.Trim();
       
       foreach($r in $recp)
       {
             $msg.To.Add($r)
       }
       
       $enddate = (Get-Date).tostring("dd.MM.yyyy")  
       $msg.Subject = "Lizenzauswertung $Customer " + $enddate  
       $msg.Body = $Fragments
       $msg.IsBodyHtml = 0 
       $msg.BodyEncoding = New-Object System.Text.UTF8Encoding

       
       $smtp.Send($msg)
}


function Read-Configuration
{
       trap
       { 
             $error
             $error.clear()
             return $false
       }
       
       
       $xmlSMTP = New-Object xml
       $xmlSMTP.Load("C:\Scripte\0365\LizenzReport\config_smtp.xml")  
       
       $xmlMailRecipients = New-Object xml
       $xmlMailRecipients.Load("C:\Scripte\0365\LizenzReport\config_MailRecipient.xml")   
        
       $global:smtpserver = $xmlSMTP.Configuration.SMTPServer
       $global:smtpport = $xmlSMTP.Configuration.SMTPPort
       $global:smtpfrom = $xmlSMTP.Configuration.SMTPFrom
       $global:smtpuser = $xmlSMTP.Configuration.SMTPUser
       $global:smtppassword = $xmlSMTP.Configuration.SMTPPassword
       $global:smtpusessl = $xmlSMTP.Configuration.SMTPSSL
       
       [array]$global:mailrecipients=@()
       $xmr = $xmlMailRecipients.Configuration.MailRecipients
       foreach ($mr in $xmr)
       {
             $global:mailrecipients += $mr.MailRecipient
       } 
}

Read-Configuration 

Send-Mail $global:smtpserver $global:mailrecipients $MailSubject $MailReport $global:smtpusessl $global:smtpport 


Das Ergebnis sieht in etwa wie folgt aus:

Lizenz Übersicht: Test Test
AccountSkuId Total Consumed Unassigned
----- -------- ----------
reseller-account:EXCHANGESTANDARD 51 51 0
reseller-account:O365_BUSINESS_PREMIUM 1 1 0


GroupName TotalUserCount
--------------
ABR_Standort1 19
ABR_Standort2 24
ABR_Standort3 10


UserPrincipalName IsLicensed $_.Licenses.AccountSkuId
---------- ------------------------
test1@test.de True reseller-account:EXCHANGESTANDARD


nun zu dem Problem.

Ich Bekomme meine Gruppen richtig gefiltert wie gewünscht nun sind aber weil jemand nicht richtig aufpasst oder ein Nutzer in ein Freigegebenespostfach umgewandelt wurde, Nutzer in den Gruppen welche keine Lizenz mehr haben.

Ich brauche also quasi einen extra filter welcher mir bei den totalen Usern nur User mit einer gültigen Lizenz ausgibt. Oder auch beides nebeneinander das wäre noch besser, dann kann man gleich aufräumen.

Beispiel Ausgabe: (Wie ich es gerne hätte)
GroupName TotalUserCount UsersLicensed
ABR_Standort1 19 18
ABR_Standort2 24 20
ABR_Standort3 10 10


Das Script Stück in der Funktion GetABR ist so fast 1:1 von Microsoft kopiert, der part ab "#check if any licenses are assigned via this group" ist für die Erfassung von per Azure zugewiesenen Lizenzen gedacht und daher nicht hilfreich, wenn ich also diesen block durch denn "filter" tauschen könnte das wäre ideal.


Ich danke im voraus für jeden Konstruktiven Vorschlag.


#Die Formatierung will ich zwar auch noch schön haben ist aber zweitrangig, wenn aber trotzdem jemand Vorschläge hat raus damit ;)

Content-Key: 357421

Url: https://administrator.de/contentid/357421

Printed on: April 18, 2024 at 10:04 o'clock

Member: GeretCondit
GeretCondit Feb 28, 2018, updated at Mar 28, 2018 at 10:55:12 (UTC)
Goto Top
Ich habe die Lösung jetzt selber fertig gebaut.

Hier einmal meine Fertig Lösung, schickt ihr euch das ganze per Mail ist es sogar HTML Formatiert face-smile

#This Script Reads the Users and Licenses from a certain Office 365 Tennant.
#It also reads the Groups.
#After that a Report is Generated and send vie Mail to the Recipioents listed in "config_MailRecipient.xml"  
#This Script needs to be run with ADMINISTRATION rights!

Set-ExecutionPolicy unrestricted

$Customer = "Test Kunde" #CustomerName  
$Username = "test@test.de"  
$Password = ConvertTo-SecureString 'Password' -AsPlainText -Force  


#Login for Office Tannant
$UserCredential = New-Object System.Management.Automation.PSCredential $Username, $Password
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Connect-MsolService -Credential $UserCredential
Import-Module MSOnline
Import-PSSession $Session




#Get the Data

#Gets the Different Licenses (In Numbers)
function GetLic {
$table = @{expr={$_.AccountSkuID};label="AccountSkuId"},  
 @{expr={$_.ActiveUnits};label="Total"},#Total  
 @{expr={$_.ConsumedUnits};label="Consumed"},#Consumed  
 @{expr={$_.activeunits-$_.consumedunits};label="Unassigned"}#Not Assigend  
Get-MsolAccountSku | sort activeunits -desc | Select-Object $table | ConvertTo-Html | ft $table -auto 
}
$AllLicens = GetLic | Format-List | Out-String

#Reads out all users and shows Licensing Status (Active/Inactive)
function GetUserLic {
Get-MSOLUser -All | select userprincipalname,islicensed,{$_.Licenses.AccountSkuId} | sort islicensed -Desc | ConvertTo-HTML
}
$UserStatus = GetUserLic | Out-String

#Searches for the ABR groups and Counts the Members
function GetABR { Get-MsolGroup -All | Where-Object {$_.DisplayName -like 'ABR*'} | Foreach {  
    $groupId = $_.ObjectId;
    $groupName = $_.DisplayName;
    $groupLicenses = $_.Licenses | Select -ExpandProperty SkuPartNumber
    $totalCount = 0;
    $licenseAssignedCount = 0;
    $licenseErrorCount = 0;

    Get-MsolGroupMember -All -GroupObjectId $groupId |
    #get full info about each user in the group
    Get-MsolUser -ObjectId {$_.ObjectId} | Foreach {
        $user = $_;
        $totalCount++

     
        #check if any licenses are assigned via this group
        if($user.isLicensed -eq $TRUE )
        {
            $licenseAssignedCount++
        }
        #check if user has any licenses that failed to be assigned from this group
        if ($user.isLicensed -like $False  )
        {
            $licenseErrorCount++
        }   

    }
    

    #aggregate results for this group
    New-Object Object |
                    Add-Member -NotePropertyName GroupName -NotePropertyValue $groupName -PassThru |
                    Add-Member -NotePropertyName TotalUserCount -NotePropertyValue $totalCount -PassThru |
                    Add-Member -NotePropertyName LicensedUserCount -NotePropertyValue $licenseAssignedCount -PassThru |
                    Add-Member -NotePropertyName LicenseErrorCount -NotePropertyValue $licenseErrorCount -PassThru

    }| ConvertTo-Html -Property GroupName,TotalUserCount, LicensedUserCount, LicenseErrorCount #Gives out the Totall of Users in the ABR Groups

}
$ABR = GetABR | Out-String


#Titel
$Title= @"   
Lizenz Übersicht: $Customer <br/>
"@  
#Converts the Parts together
$Empty = @"  
<br/>
"@  
$Fragments = $Title + $Empty + $AllLicens + $Empty + $ABR + $Empty + $UserStatus

#Add a footer 
$footer=("Ausgeführt am {0} von {1}\{2}. Created by GeretCondit" -f (Get-Date -displayhint date),$env:userdomain,$env:username)   
$fragments+= $Empty + $footer 


#Functions to Send the Mail
function Send-Mail($smtpServer,[array]$recp,$subj,$body, $smtpusessl, $smtpport)
{




       $msg = new-object Net.Mail.MailMessage
       $smtp = new-object Net.Mail.SmtpClient($smtpServer, $smtpport)
    
       if ($smtpusessl -eq 1)
       {      
             $smtp.EnableSsl = $true
       }            
       if ($global:smtpuser.Trim() -ne "")  
       {
             $smtp.Credentials = New-Object Net.NetworkCredential ($global:smtpuser.Trim(), $global:smtppassword.Trim())
       }
       
       $msg.From = $global:smtpfrom.Trim();
       
       foreach($r in $recp)
       {
             $msg.To.Add($r)
       }
       
       $enddate = (Get-Date).tostring("dd.MM.yyyy")  
       $msg.Subject = "Lizenzauswertung $Customer " + $enddate  
       $msg.Body = $Fragments
       $msg.IsBodyHtml = 1 
       $msg.BodyEncoding = New-Object System.Text.UTF8Encoding

       
       $smtp.Send($msg)
}


function Read-Configuration
{
       trap
       { 
             $error
             $error.clear()
             return $false
       }
       
       
       $xmlSMTP = New-Object xml
       $xmlSMTP.Load("W:\Arbeit\Scripte\Fertig\PowerShell\0365\LizenzReport\config_smtp.xml")  
       
       $xmlMailRecipients = New-Object xml
       $xmlMailRecipients.Load("W:\Arbeit\Scripte\Fertig\PowerShell\0365\LizenzReport\config_MailRecipient.xml")  
        
       $global:smtpserver = $xmlSMTP.Configuration.SMTPServer
       $global:smtpport = $xmlSMTP.Configuration.SMTPPort
       $global:smtpfrom = $xmlSMTP.Configuration.SMTPFrom
       $global:smtpuser = $xmlSMTP.Configuration.SMTPUser
       $global:smtppassword = $xmlSMTP.Configuration.SMTPPassword
       $global:smtpusessl = $xmlSMTP.Configuration.SMTPSSL
       
       [array]$global:mailrecipients=@()
       $xmr = $xmlMailRecipients.Configuration.MailRecipients
       foreach ($mr in $xmr)
       {
             $global:mailrecipients += $mr.MailRecipient
       } 
}

Read-Configuration 

Send-Mail $global:smtpserver $global:mailrecipients $MailSubject $MailReport $global:smtpusessl $global:smtpport