Reports.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using namespace Microsoft.Graph.PowerShell.Models

function Get-GraphReport       {
    <#
        .Synopsis
            Gets reports from MS Graph
        .Example
            >Get-GraphReport -Report MailboxUsageDetail | ft "Display Name", "Storage Used (Byte)"
            Displays mailbox storage used by users - note that
            fields have 'friendly' names which need to be wrapped in quotes
    #>

    [cmdletbinding(DefaultParameterSetName="None")]
    param   (
        #The report to Fetch
        [ValidateSet(
                'EmailActivityCounts', 'EmailActivityUserCounts', 'EmailActivityUserDetail',
                'EmailAppUsageAppsUserCounts', 'EmailAppUsageUserCounts', 'EmailAppUsageUserDetail', 'EmailAppUsageVersionsUserCounts',
                'MailboxUsageDetail', 'MailboxUsageMailboxCounts', 'MailboxUsageQuotaStatusMailboxCounts', 'MailboxUsageStorage',
                'Office365ActivationCounts', 'Office365ActivationsUserCounts', 'Office365ActivationsUserDetail',
                'Office365ActiveUserCounts', 'Office365ActiveUserDetail',  'Office365GroupsActivityCounts', 'Office365GroupsActivityDetail',
                'Office365GroupsActivityFileCounts', 'Office365GroupsActivityGroupCounts', 'Office365GroupsActivityStorage',
                'Office365ServicesUserCounts',
                'OneDriveActivityFileCounts', 'OneDriveActivityUserCounts', 'OneDriveActivityUserDetail', 'OneDriveUsageAccountCounts',
                'OneDriveUsageAccountDetail', 'OneDriveUsageFileCounts', 'OneDriveUsageStorage',
                'SharePointActivityFileCounts', 'SharePointActivityPages', 'SharePointActivityUserCounts',
                'SharePointActivityUserDetail', 'SharePointSiteUsageDetail', 'SharePointSiteUsageFileCounts',
                'SharePointSiteUsagePages', 'SharePointSiteUsageSiteCounts', 'SharePointSiteUsageStorage',
                'SkypeForBusinessActivityCounts', 'SkypeForBusinessActivityUserCounts', 'SkypeForBusinessActivityUserDetail',
                'SkypeForBusinessDeviceUsageDistributionUserCounts','SkypeForBusinessDeviceUsageUserCounts', 'SkypeForBusinessDeviceUsageUserDetail',
                'SkypeForBusinessOrganizerActivityCounts', 'SkypeForBusinessOrganizerActivityMinuteCounts',
                'SkypeForBusinessOrganizerActivityUserCounts', 'SkypeForBusinessParticipantActivityCounts',
                'SkypeForBusinessParticipantActivityMinuteCounts', 'SkypeForBusinessParticipantActivityUserCounts',
                'SkypeForBusinessPeerToPeerActivityCounts', 'SkypeForBusinessPeerToPeerActivityMinuteCounts', 'SkypeForBusinessPeerToPeerActivityUserCounts',
                'TeamsDeviceUsageDistributionUserCounts', 'TeamsDeviceUsageUserCounts', 'TeamsDeviceUsageUserDetail',
                'TeamsUserActivityCounts', 'TeamsUserActivityUserCounts', 'TeamsUserActivityUserDetail',
                'YammerActivityCounts', 'YammerActivityUserCounts', 'YammerActivityUserDetail', 'YammerDeviceUsageDistributionUserCounts',
                'YammerDeviceUsageUserCounts', 'YammerDeviceUsageUserDetail', 'YammerGroupsActivityCounts',
                'YammerGroupsActivityDetail', 'YammerGroupsActivityGroupCounts'
        )]
        [parameter(Mandatory=$true)]
        $Report,
        #Date for the report - this should be a date in the past 30 days. If specified, -Period is ignored. Reports ending in Count, Storage or pages don't support date filtering
        [DateTime]$Date,
        #The range of time for the report in the form "Dn" where n is the number of days. The default is D7, except for Office365Activation activation reports
        [ValidateSet("D7", "D30", "D90", "D180")]
        $Period,
        #If specified the data will be written in CSV format to the path provided, otherwise it will be output to the pipeline
        $Path
    )
    if     ($Date)    {
        if ($report -match 'Counts$|Pages$|Storage$') {Write-Warning -Message 'Reports ending with Counts, Pages or Storage do not support date filtering' ; return }
        if ($report -match '^Office365Activation')    {Write-Warning -Message 'Office365Activation Reports do not support any filtering.'  ; return }
        if ($report -eq    'MailboxUsageDetail')      {Write-Warning -Message 'MailboxUsageDetail does not support date filtering.' ; return}
        $uri = "$GraphUri/reports/microsoft.graph.Get{0}(date={1:yyyy-MM-dd})" -f $Report , $Date
    }
    elseif ($Period)  {
        if ($report -match '^Office365Activation')    {Write-Warning -Message 'Office365Activation Reports do not support any filtering.'  ; return }
        $uri = "$GraphUri/reports/microsoft.graph.Get{0}(period='{1}')"        -f $Report , $Period
    }
    else              {
      if ($report -notmatch '^Office365Activation')  {
        $uri = "$GraphUri/reports/microsoft.graph.Get{0}(period='d7')"         -f $Report
      }
      else {
        $uri = "$GraphUri/reports/microsoft.graph.Get{0}"                      -f $Report
      }
    }
    if ($Path) { Invoke-GraphRequest -Method GET -uri $uri -OutputFilePath $Path}
    else       {
        $Path = [System.IO.Path]::GetTempFileName()
        Invoke-GraphRequest -Method GET -uri $uri -OutputFilePath $Path
        Import-Csv  $Path
        Remove-Item $Path
        }
}

function Get-GraphSignInLog    {
    <#
      .synopsis
        Gets the audit log -requires a priviledged account
      .Description
        This command calls https://graph.microsoft.com/beta/auditLogs/signIns
        which requires consent to use the AuditLog.Read.All Scope this can only be granted to Azure AD apps.
      .Example
        >
        >Get-GraphSignInLog |
        > select Date,UserPrincipalName,appDisplayName,ipAddress,clientAppUsed,browser,device,city,lat,long |
        > Export-Excel -Path .\signin.xlsx -AutoSize -IncludePivotTable -PivotTableName Signins -PivotRows appdisplayName -PivotColumns browser -PivotData @{date='Count'} -show

        Gets the sign-in Log and exports it Excel, creating a PivotTable
    #>

    [cmdletbinding()]
    [outputtype([Microsoft.Graph.PowerShell.Models.MicrosoftGraphSignIn])]
    param   (
            $top = 200
    )
    $i = 1
    Write-Progress -Activity 'Getting Sign-in Auditlog'

    $result  = Invoke-GraphRequest  -Method get -Uri "$GraphUri/auditLogs/signIns?`$top=$top" -SkipHttpErrorCheck -StatusCodeVariable status
    if ($result.error)              {
            Write-Progress -Activity 'Getting Sign-in Auditlog' -Completed
            Write-Warning "An error was returned: '$($result.error.message)' code: $($result.error.code) "
    }
    if ($status -notmatch "2\d\d")  {Write-Warning "Status code returned was $Status ($([System.Net.HttpStatusCode]$status)) which does not look like success."}

    $records = $result.value
    while ($result.'@odata.nextLink' -and $records.count -lt $top) {
        $i ++
        Write-Progress -Activity 'Getting Sign-in Auditlog' -CurrentOperation "Page $i"
        $result   = Invoke-GraphRequest  -Method get -Uri $result.'@odata.nextLink'
        $records += $result.value
    }

    foreach ($r in $records) {
        $r.pstypenames.add('GraphSigninLog')
        $r['RiskEventTypesV2'] = $r['RiskEventTypes_V2'] ;
        [void]$r.Remove('RiskEventTypes_V2');
        New-Object -TypeName MicrosoftGraphSignIn -Property $r
    }
    Write-Progress -Activity 'Getting Sign-in Auditlog'-Completed


}

function Get-GraphDirectoryLog {
    <#
      .synopsis
        Gets the Directory audit log -requires a priviledged account
      .Description
        This command calls https://graph.microsoft.com/beta/auditLogs/directoryAudits
        which requires consent to use the AuditLog.Read.All Scope this can only be granted to Azure AD apps.

    #>

    [cmdletbinding()]
    [outputType([Microsoft.Graph.PowerShell.Models.MicrosoftGraphDirectoryAudit])]
    param   (
    [switch]$all,
    $Top = 100
    )
    $i = 1
    Write-Progress -Activity 'Getting Directory Audits log'
    $uri = "$GraphUri/auditLogs/directoryAudits"
    if (-not $all) {$uri += "?`$Top=$Top"}
    $result  = Invoke-GraphRequest  -Method get -Uri $uri -SkipHttpErrorCheck -StatusCodeVariable status
    if ($result.error)              {Write-Warning "An error was returned: '$($result.error.message)' - code: $($result.error.code) "}

    $records = $result.value
    while ($result.'@odata.nextLink' -and  $records.Count -lt $top) {
        $i ++
        Write-Progress -Activity 'Getting Directory Audits log' -CurrentOperation "Page $i"
        $result   = Invoke-GraphRequest  -Method get -Uri $result.'@odata.nextLink'
        $records += $result.value
    }
    foreach ($r in $records) {
        New-Object -TypeName MicrosoftGraphDirectoryAudit -Property $r
    }
    Write-Progress -Activity 'Getting Directory Audits log' -Completed
}