PowerShell Setup: Control 2.7 - Vendor and Third-Party Risk Management
This playbook provides PowerShell automation scripts for Control 2.7.
Prerequisites
# Install Power Platform admin module
Install-Module -Name Microsoft.PowerApps.Administration.PowerShell -Force
# Connect to Power Platform (interactive authentication)
Add-PowerAppsAccount
# For automated/unattended scenarios, use service principal authentication:
# $appId = "<Application-Client-ID>"
# $secret = "<Client-Secret>"
# $tenantId = "<Tenant-ID>"
# Add-PowerAppsAccount -ApplicationId $appId -ClientSecret $secret -TenantID $tenantId
# Verify connection
Get-AdminPowerAppEnvironment | Select-Object DisplayName, EnvironmentName | Format-Table
Get Connectors in Use
# Get all apps across environments
$environments = Get-AdminPowerAppEnvironment
$connectorUsage = @()
foreach ($env in $environments) {
Write-Host "Scanning environment: $($env.DisplayName)" -ForegroundColor Cyan
# Get apps in environment
$apps = Get-AdminPowerApp -EnvironmentName $env.EnvironmentName
foreach ($app in $apps) {
Write-Host " App: $($app.DisplayName)"
}
# Get flows in environment
$flows = Get-AdminFlow -EnvironmentName $env.EnvironmentName
foreach ($flow in $flows) {
Write-Host " Flow: $($flow.DisplayName)"
}
}
Write-Host "`nTotal environments scanned: $($environments.Count)"
Export Connector Inventory
# Export detailed connector inventory
function Export-ConnectorInventory {
param(
[string]$OutputPath = ".\ConnectorInventory.csv"
)
$environments = Get-AdminPowerAppEnvironment
$inventory = @()
foreach ($env in $environments) {
# Get DLP policies for environment
$dlpPolicies = Get-DlpPolicy | Where-Object {
$_.environments.name -contains $env.EnvironmentName -or
$_.environmentType -eq "AllEnvironments"
}
$inventory += [PSCustomObject]@{
EnvironmentName = $env.DisplayName
EnvironmentId = $env.EnvironmentName
EnvironmentType = $env.EnvironmentType
DLPPoliciesApplied = ($dlpPolicies | Measure-Object).Count
AssessmentDate = Get-Date -Format "yyyy-MM-dd"
}
}
$inventory | Export-Csv -Path $OutputPath -NoTypeInformation
Write-Host "Exported connector inventory to: $OutputPath" -ForegroundColor Green
return $inventory
}
# Run export
$connectorInventory = Export-ConnectorInventory -OutputPath ".\VendorConnectorInventory.csv"
$connectorInventory | Format-Table
Review Connector Permissions
# Review DLP policies and connector classifications
function Get-ConnectorPolicyReport {
$dlpPolicies = Get-DlpPolicy
$report = @()
foreach ($policy in $dlpPolicies) {
Write-Host "`n=== Policy: $($policy.displayName) ===" -ForegroundColor Cyan
# Get connector groups
$businessGroup = $policy.connectorGroups | Where-Object { $_.classification -eq "General" }
$nonBusinessGroup = $policy.connectorGroups | Where-Object { $_.classification -eq "Confidential" }
$blockedGroup = $policy.connectorGroups | Where-Object { $_.classification -eq "Blocked" }
$report += [PSCustomObject]@{
PolicyName = $policy.displayName
PolicyType = $policy.environmentType
BusinessConnectors = ($businessGroup.connectors | Measure-Object).Count
NonBusinessConnectors = ($nonBusinessGroup.connectors | Measure-Object).Count
BlockedConnectors = ($blockedGroup.connectors | Measure-Object).Count
CreatedTime = $policy.createdTime
LastModified = $policy.lastModifiedTime
}
}
return $report
}
$policyReport = Get-ConnectorPolicyReport
$policyReport | Format-Table -AutoSize
$policyReport | Export-Csv -Path ".\DLPPolicyReport.csv" -NoTypeInformation
Monitor Custom Connectors
# Get all custom connectors across environments
function Get-CustomConnectorInventory {
$environments = Get-AdminPowerAppEnvironment
$customConnectors = @()
foreach ($env in $environments) {
$connectors = Get-AdminPowerAppConnector -EnvironmentName $env.EnvironmentName
foreach ($connector in $connectors) {
$customConnectors += [PSCustomObject]@{
ConnectorName = $connector.displayName
ConnectorId = $connector.name
Environment = $env.DisplayName
Publisher = $connector.properties.publisher
CreatedBy = $connector.properties.createdBy.displayName
CreatedTime = $connector.properties.createdTime
ApiDefinitionUrl = $connector.properties.apiDefinitionUrl
}
}
}
return $customConnectors
}
$customConnectors = Get-CustomConnectorInventory
Write-Host "`nCustom Connectors Found: $($customConnectors.Count)" -ForegroundColor Yellow
$customConnectors | Format-Table -AutoSize
$customConnectors | Export-Csv -Path ".\CustomConnectorInventory.csv" -NoTypeInformation
Audit Dynamic Tool Usage
# Audit tool and plugin usage across agents
function Get-DynamicToolUsage {
param(
[DateTime]$StartDate = (Get-Date).AddDays(-30),
[string]$OutputPath = ".\Tool-Usage-Audit"
)
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
Write-Host "Auditing dynamic tool usage..." -ForegroundColor Cyan
# Get all environments
$environments = Get-AdminPowerAppEnvironment
$toolUsage = @()
foreach ($env in $environments) {
Write-Host "Scanning: $($env.DisplayName)" -ForegroundColor Yellow
# Get connectors in use
$connectors = Get-AdminPowerAppConnector -EnvironmentName $env.EnvironmentName
foreach ($connector in $connectors) {
$toolUsage += [PSCustomObject]@{
Environment = $env.DisplayName
ConnectorName = $connector.displayName
ConnectorId = $connector.name
Publisher = $connector.properties.publisher
PublisherType = if ($connector.properties.publisher -eq "Microsoft") { "First-Party" }
elseif ($connector.properties.isTrusted) { "Verified" }
else { "Community/Custom" }
CreatedBy = $connector.properties.createdBy.displayName
CreatedTime = $connector.properties.createdTime
RiskLevel = if ($connector.properties.publisher -ne "Microsoft") { "Review Required" } else { "Standard" }
}
}
}
# Export findings
$toolUsage | Export-Csv -Path "$OutputPath\Tool-Usage-Audit.csv" -NoTypeInformation
# Identify high-risk tools
$highRisk = $toolUsage | Where-Object { $_.PublisherType -eq "Community/Custom" }
if ($highRisk.Count -gt 0) {
Write-Host "`nHIGH-RISK TOOLS DETECTED: $($highRisk.Count)" -ForegroundColor Red
$highRisk | Format-Table Environment, ConnectorName, Publisher -AutoSize
$highRisk | Export-Csv -Path "$OutputPath\High-Risk-Tools.csv" -NoTypeInformation
}
Write-Host "`nAudit complete. Output: $OutputPath" -ForegroundColor Green
return $toolUsage
}
# Run audit
# Get-DynamicToolUsage
Complete Configuration Script
<#
.SYNOPSIS
Complete vendor and third-party risk assessment for Control 2.7
.DESCRIPTION
Executes end-to-end vendor risk assessment including:
- Connector inventory collection
- DLP policy analysis
- Third-party risk identification
- Compliance report generation
.PARAMETER OutputPath
Path for output reports
.EXAMPLE
.\Configure-Control-2.7.ps1 -OutputPath ".\VendorRisk"
.NOTES
Last Updated: January 2026
Related Control: Control 2.7 - Vendor and Third-Party Risk Management
#>
param(
[string]$OutputPath = ".\VendorRisk-Report"
)
try {
Write-Host "=== Control 2.7: Vendor and Third-Party Risk Configuration ===" -ForegroundColor Cyan
# Connect to Power Platform
Add-PowerAppsAccount
# Ensure output directory exists
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
# Get all environments
$environments = Get-AdminPowerAppEnvironment
Write-Host "[INFO] Found $($environments.Count) environments" -ForegroundColor Cyan
# Collect connector inventory
$connectorInventory = @()
foreach ($env in $environments) {
Write-Host " Scanning: $($env.DisplayName)" -ForegroundColor Yellow
$connectors = Get-AdminPowerAppConnector -EnvironmentName $env.EnvironmentName -ErrorAction SilentlyContinue
foreach ($connector in $connectors) {
$connectorInventory += [PSCustomObject]@{
Environment = $env.DisplayName
ConnectorName = $connector.displayName
Publisher = $connector.properties.publisher
IsFirstParty = $connector.properties.publisher -eq "Microsoft"
CreatedBy = $connector.properties.createdBy.displayName
CreatedTime = $connector.properties.createdTime
AssessmentDate = Get-Date -Format "yyyy-MM-dd"
}
}
}
# Export connector inventory
$connectorInventory | Export-Csv -Path "$OutputPath\ConnectorInventory.csv" -NoTypeInformation
Write-Host "`n[INFO] Connector inventory exported: $($connectorInventory.Count) connectors" -ForegroundColor Cyan
# Get DLP policies
$dlpPolicies = Get-DlpPolicy -ErrorAction SilentlyContinue
if ($dlpPolicies) {
Write-Host "[INFO] Found $($dlpPolicies.Count) DLP policies" -ForegroundColor Cyan
$dlpPolicies | Select-Object displayName, environmentType, createdTime |
Export-Csv -Path "$OutputPath\DLPPolicies.csv" -NoTypeInformation
}
# Identify third-party connectors
$thirdParty = $connectorInventory | Where-Object { -not $_.IsFirstParty }
if ($thirdParty.Count -gt 0) {
Write-Host "[WARN] Third-party connectors found: $($thirdParty.Count)" -ForegroundColor Yellow
$thirdParty | Export-Csv -Path "$OutputPath\ThirdPartyConnectors.csv" -NoTypeInformation
}
# Summary
Write-Host "`n=== Summary ===" -ForegroundColor Cyan
Write-Host "Total Environments: $($environments.Count)"
Write-Host "Total Connectors: $($connectorInventory.Count)"
Write-Host "First-Party: $(($connectorInventory | Where-Object { $_.IsFirstParty }).Count)"
Write-Host "Third-Party: $($thirdParty.Count)"
Write-Host "`n[PASS] Control 2.7 configuration completed successfully" -ForegroundColor Green
}
catch {
Write-Host "[FAIL] Error: $($_.Exception.Message)" -ForegroundColor Red
Write-Host "[INFO] Stack trace: $($_.ScriptStackTrace)" -ForegroundColor Yellow
exit 1
}
finally {
# Cleanup connections if applicable
# Note: Add-PowerAppsAccount does not require explicit disconnect
}
Related Playbooks
- Portal Walkthrough - Step-by-step portal configuration
- Verification & Testing - Assessment procedures
- Troubleshooting - Common issues and solutions
Updated: January 2026 | Version: v1.2