New-FlowOverview.ps1

<#PSScriptInfo
.VERSION 1.1
.GUID 67ac7419-9dc8-4808-8492-c160a6bc4252
.AUTHOR
 Maarten Peeters - Cloud Securitea - https://www.cloudsecuritea.com
.COMPANYNAME
 Cloud Securitea
.COPYRIGHT
.TAGS
 Flow, Administration, report
.LICENSEURI
.PROJECTURI
.ICONURI
.EXTERNALMODULEDEPENDENCIES
 MSOnline
 Microsoft.PowerApps.Administration.PowerShell
 Microsoft.PowerApps.PowerShell
.RELEASENOTES
 Version 1.0: Original published version.
 Version 1.1: Environment Type wasn't using the correct variable so the output was empty. Updated the variable
#>
 

<#
.SYNOPSIS
 Quickly generate an overview of the current Flows in your environment
 
.DESCRIPTION
 This script will generate a HTML file to list all Flows per Flow environment
 
.PARAMETER LogPath
 Enter the full path to store the HTML report of the Flow overview
 For example: C:\Install
 
.EXAMPLE
 New-FlowOverview.ps1 -LogPath "C:\Install"
 
 .NOTES
 Version: 1.1
 Author: Maarten Peeters
 Creation Date: 26-09-2019
 Purpose/Change: Quickly generate an overview of the current Flows in your environment
#>


param(
    [Parameter(mandatory=$true)]
    [string] $LogPath
)

try{
    #Verify if MSOnline Module is available
    if (Get-Module -ListAvailable -Name MSonline) {
        #Import MSOnline Module
        import-module MSOnline -ErrorAction SilentlyContinue

        #Verify if the Microsoft.PowerApps.Administration.PowerShell Module and Microsoft.PowerAPps.PowerShell are installed
        if (Get-Module -ListAvailable -Name Microsoft.PowerApps.Administration.PowerShell) {
            if (Get-Module -ListAvailable -Name Microsoft.PowerApps.PowerShell) {
        
                #Test if logpath exists
                If(Test-Path $LogPath) { 
                    #Start script
                    Try{
                        #Object collections
                        $flowCollection = @()
                        $environmentCollection = @()

                        #Connect to the correct O365 Tenant
                        Connect-MsolService 
                        
                        #Connect to the Flow Environment
                        Add-PowerAppsAccount

                        #Retrieve all users UPN and ID
                        $users = Get-MsolUser -All | Select-Object UserPrincipalName, ObjectId | Sort-Object DisplayName

                        #Retrieve all flow environments
                        $environments = Get-FlowEnvironment | Sort-Object EnvironmentName
                        
                        #Retrieve all flows
                        $flows = get-AdminFlow | Sort-Object EnvironmentName
                      
                        #loop through all environments
                        foreach($environment in $environments){
                            #fill the collection with information
                            $envProperties = $environment.internal.properties
                            [datetime]$createdTime = $envProperties.createdTime
                            $environmentCollection += new-object psobject -property @{displayName = $envProperties.displayName;InternalName = $environment.EnvironmentName;SKU = $envProperties.environmentSku;EnvType = $envProperties.environmentType;Region = $envProperties.azureRegionHint;Created = $createdTime.ToString("dd-MM-yyyy HH:mm:ss");CreatedBy = $envProperties.createdby.displayname}
                        }

                        #loop through all flows
                        foreach($flow in $flows){
                            #fill the collection with information
                            $flowProperties = $flow.internal.properties
                            $creatorName = $users | where-object{$_.ObjectId -eq $flowProperties.creator.UserID}
                            
                            $triggers = $flowProperties.definitionsummary.triggers
                            $actions = $flowProperties.definitionsummary.actions | where-object {$_.swaggerOperationId}
                            
                            $triggerString = ""
                            foreach($trigger in $triggers){
                                if($triggerString -ne ""){
                                    $triggerString = $triggerString + "<br />"
                                }
                                $triggerString = $triggerString + "$($trigger.swaggerOperationId)"
                            }
                            
                            $actionsString = ""
                            foreach($action in $actions){
                                if($actionsString -ne ""){
                                    $actionsString = $actionsString + "<br />"
                                }
                                $actionsString = $actionsString + "$($action.swaggerOperationId)"
                            }
                            
                            
                            [datetime]$modifiedTime = $flow.LastModifiedTime
                            [datetime]$createdTime = $flowProperties.createdTime
                            
                            $flowCollection += new-object psobject -property @{displayName = $flowProperties.displayName;environment = $flowProperties.Environment.name;State = $flowProperties.State;Triggers = $triggerString;Actions = $actionsString;Created = $createdTime.ToString("dd-MM-yyyy HH:mm:ss");Modified = $modifiedTime.ToString("dd-MM-yyyy HH:mm:ss");CreatedBy = $creatorName.userPrincipalName}
                        }    

                        #We now have our collections so we are building the HTML page to get a direct view
                        #List of all Flow environments
                        $article = "<h2>List of all Flow environments</h2>"
                        $article += "<table>
                                    <tr>
                                        <th>displayName</th>
                                        <th>InternalName</th>
                                        <th>SKU</th>
                                        <th>Type</th>
                                        <th>Region</th>
                                        <th>Created</th>
                                        <th>CreatedBy</th>
                                    </tr>"

                        
                        foreach($environmentColl in $environmentCollection){
                        $article += "<tr>
                                        <td>$($environmentColl.displayName)</td>
                                        <td>$($environmentColl.InternalName)</td>
                                        <td>$($environmentColl.SKU)</td>
                                        <td>$($environmentColl.EnvType)</td>
                                        <td>$($environmentColl.Region)</td>
                                        <td>$($environmentColl.Created)</td>
                                        <td>$($environmentColl.CreatedBy)</td>
                                    </tr>"

                        }
                        
                        $article += "</table>"

                        #List of all Flows
                        $article += "<h2>List of all Flows</h2>"
                        $article += "<table>
                                    <tr>
                                        <th>displayName</th>
                                        <th>environment</th>
                                        <th>State</th>
                                        <th>Triggers</th>
                                        <th>Actions</th>
                                        <th>Created</th>
                                        <th>Modified</th>
                                        <th>CreatedBy</th>
                                    </tr>"

                        
                        foreach($flowColl in $flowCollection){
                        $article += "<tr>
                                        <td>$($flowColl.displayName)</td>
                                        <td>$($flowColl.environment)</td>
                                        <td>$($flowColl.State)</td>
                                        <td>$($flowColl.Triggers)</td>
                                        <td>$($flowColl.Actions)</td>
                                        <td>$($flowColl.Created)</td>
                                        <td>$($flowColl.Modified)</td>
                                        <td>$($flowColl.CreatedBy)</td>
                                    </tr>"

                        }
                        
                        $article += "</table>"

                        $date = get-date
                        $today = $date.ToString("ddMMyyyy_HHmm")
                        $LogPath = Join-Path $LogPath "HTMLFlowReport_$($today).html"    
                        
                        #Head
                        $head = "
                        <html xmlns=`"http://www.w3.org/1999/xhtml`">
                            <head>
                                <style>
                                    @charset `"UTF-8`";
 
                                    @media print {
                                        body {-webkit-print-color-adjust: exact;}
                                    }
                         
                                    div.container {
                                        width: 100%;
                                        border: 1px solid gray;
                                    }
                                     
                                    header {
                                        padding: 0.1em;
                                        color: white;
                                        background-color: #000033;
                                        color: white;
                                        clear: left;
                                        text-align: center;
                                        border-bottom: 2px solid #FF0066
                                    }
                                     
                                    footer {
                                        padding: 0.1em;
                                        color: white;
                                        background-color: #000033;
                                        color: white;
                                        clear: left;
                                        text-align: center;
                                        border-top: 2px solid #FF0066
                                    }
 
                                    article {
                                        margin-left: 20px;
                                        min-width:600px;
                                        min-height: 600px;
                                        padding: 1em;
                                    }
                                     
                                    th{
                                        border:1px Solid Black;
                                        border-Collapse:collapse;
                                        background-color:#000033;
                                        color:white;
                                    }
                                     
                                    th{
                                        border:1px Solid Black;
                                        border-Collapse:collapse;
                                    }
                                     
                                    tr:nth-child(even) {
                                      background-color: #dddddd;
                                    }
 
                                </style>
                            </head>
                        "

                        
                        #Header
                        $date = (get-date).tostring("dd-MM-yyyy")
                        $header = "
                            <h1>Flow Report</h1>
                            <h5>$($date)</h5>
                        "

                        
                        #Footer
                        $Footer = "
                            Copyright &copy;
                        "

                        
                        #Full HTML
                        $HTML = "
                            $($Head)
                            <body class=`"Inventory`">
                                <div class=`"container`">
                                    <header>
                                        $($Header)
                                    </header>
                                     
                                    <article>
                                        $($article)
                                    </article>
                                             
                                    <footer>
                                        $($footer)
                                    </footer>
                                </div>
                            </body>
                            </html>
                        "
 
                        add-content $HTML -path $LogPath

                        Write-Host "Flow overview created at $($LogPath), it will also open automatically in 5 seconds" -foregroundcolor green

                        start-sleep -s 5
                        Invoke-Item $LogPath
                    }
                    catch{
                        write-host "Error occurred: $($_.Exception.Message), please post this error on https://www.cloudsecuritea.com" -foregroundcolor red
                    }
                } Else { 
                    Write-Host "The path $($LogPath) could not be found. Please enter a correct path to store the Office 365 subscription and license overview" -foregroundcolor yellow
                }
            }
            Else{Write-Host "The new Microsoft.PowerApps.PowerShell Module is not installed. Please install using the link in the blog" -foregroundcolor yellow}
        }
        Else{Write-Host "The new Microsoft.PowerApps.Administration.PowerShell Module is not installed. Please install using the link in the blog" -foregroundcolor yellow}
    } else {
        Write-Host "MSOnline module not loaded. Please install the MSOnline module with Install-Module MSOnline" -foregroundcolor yellow
    }
}
catch{
    write-host "Error occurred: $($_.Exception.Message)" -foregroundcolor red
}