By Robert Dyjas 3 months ago • Edit this post
So you designed and implemented Data Loss Prevention policy in Power Automate. Now it's time to check if there was any impact on existing flows.
Let's start with installing proper modules. Check out PowerShell Cmdlets for PowerApps and Flow creators and administrators for all the details. For now what we need is:
# Install admin module for current user only
Install-Module -Name Microsoft.PowerApps.Administration.PowerShell -Scope CurrentUser
# OR
# Install admin module for everyone
Install-Module -Name Microsoft.PowerApps.Administration.PowerShell
We're connecting with Add-PowerAppsAccount
.
NOTE: Remember that admin cmdlets will only list data from the environments you have access to. Make sure to use the account with proper permission level.
For one-time check we don't have to care about unattended authentication so let's just run it with default options. We might need to respond to MFA challenge, depending on our account settings:
Add-PowerAppsAccount
Let's get all the flows and save them to variable:
$flows = Get-AdminFlow
By checking first non-empty element from the array, we can inspect the properties we have on each flow:
$nonEmptyFlows = $flows | Where-Object {$_.FlowName}
$f = $nonEmptyFlows | Select-Object -First 1
$f
# Returns
FlowName : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Enabled : True
DisplayName : Send a customized email when a new file is added
UserType :
CreatedTime : 2020-03-26T08:38:08.6649446Z
CreatedBy : @{tenantId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; objectId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; us
erId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; userType=ActiveDirectory}
LastModifiedTime : 2020-03-26T08:42:32.4957819Z
EnvironmentName : Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Internal : @{name=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; id=/providers/Microsoft.ProcessSimple/environments/De
fault-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/flows/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; type=Micros
oft.ProcessSimple/environments/flows; properties=}
Notice that for the environments with no flows, we'll receive empty object. In my case first object from the array is empty:
$flows[0]
# Returns
value
-----
{}
Ok, we now have all the flows, but do we only have Enabled
property to check flow status? 🤔
We have more, but they are hidden a little bit. Let's check what is under Internal
:
NOTE: Remember to use
Format-List
. Otherwise, you might not see all the properties (same applies to| Select-Object *
).
PS> $f.internal | Format-List
# Returns
name : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
id : /providers/Microsoft.ProcessSimple/environments/Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/flows/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
type : Microsoft.ProcessSimple/environments/flows
properties : @{apiId=/providers/Microsoft.PowerApps/apis/shared_logicflows; displayName=Send a customized email when a new file i
s added; state=Started; sharingType=Coauthor; createdTime=2020-03-26T08:38:08.6649446Z; lastModifiedTime=2020-03-26T
08:42:32.4957819Z; flowSuspensionReason=None; templateName=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; environment=; definitio
nSummary=; creator=; provisioningMethod=FromDefinition; flowFailureAlertSubscribed=True}
And under Properties
PS> $f.internal.properties |Format-List
apiId : /providers/Microsoft.PowerApps/apis/shared_logicflows
displayName : Send a customized email when a new file is added
state : Started
sharingType : Coauthor
createdTime : 2020-03-26T08:38:08.6649446Z
lastModifiedTime : 2020-03-26T08:42:32.4957819Z
flowSuspensionReason : None
templateName : 827b37728b634ba89e3e6678ddff334e
environment : @{name=Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; type=Microsoft.ProcessSimple/environments; id=/
providers/Microsoft.ProcessSimple/environments/Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
definitionSummary : @{triggers=System.Object[]; actions=System.Object[]; description=Send yourself or someone else a cus
tomized email whenever a new file is added to a selected SharePoint document library.}
creator : @{tenantId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; objectId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; user
Id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; userType=ActiveDirectory}
provisioningMethod : FromDefinition
flowFailureAlertSubscribed : True
Ok, now we have two candidates: State and flowSuspensionReason. The latter seems more appropriate. However, it doesn't contain any useful value - I already checked that for you.
Let's check what are the values:
PS> $nonEmptyFlows | Group {$_.internal.properties.state} -NoElement
Count Name
----- ----
73 Started
27 Stopped
9 Suspended
PS> $nonEmptyFlows | Group {$_.internal.properties.flowSuspensionReason} -NoElement
Count Name
----- ----
109 None
We'll be looking for flows with State
= Suspended. Simple Where-Object
will do:
$suspendedFlows = $nonEmptyFlows | Where-Object {$_.internal.properties.state -eq "Suspended"}
Now you have all the flows with their data saved into variable. Before reaching out to flow owners with the communication, make sure to read my previous article Custom connectors with DLP policy in Power Automate. You'll learn about the behavior of DLP for custom connectors and what happens when you disable/rollback the policy.