Private/_MainFunctions.ps1
function Set-ColourOption( [string]$value ) { if ($value -eq "False") { return "White" } elseif ($value -eq "Error") { return "Red" } elseif ($value -eq "Optional") { return "Magenta" } else { return "Green" } } function Install-XrmModule { $moduleName = "Microsoft.Xrm.Data.Powershell" $moduleVersion = "2.8.8" $module = Get-Module -ListAvailable -Name $moduleName if (!($module.Version -ge $moduleVersion )) { Write-host "Module $moduleName version $moduleVersion or higher not found, installing now" Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -AllowClobber } else { Write-host "Module $moduleName Found" Import-Module -Name $moduleName -MinimumVersion $moduleVersion -Force } } function Install-PowerAppsAdmin { $moduleName = "Microsoft.PowerApps.Administration.PowerShell" $moduleVersion = "2.0.92" $module = Get-Module -ListAvailable -Name $moduleName if (!($module.Version -ge $moduleVersion )) { Write-host "Module $moduleName version $moduleVersion or higher not found, installing now" Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -AllowClobber } else { Write-host "Module $moduleName version $moduleVersion or higher Found" Import-Module -Name $moduleName -MinimumVersion $moduleVersion -Force } } function Install-PowerAppsPowerShell { $moduleName = "Microsoft.PowerApps.PowerShell" $moduleVersion = "1.0.13" $module = Get-Module -ListAvailable -Name $moduleName if (!($module.Version -ge $moduleVersion )) { Write-host "Module $moduleName version $moduleVersion or higher not found, installing now" Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -AllowClobber } else { Write-host "Module $moduleName Found" Import-Module -Name $moduleName -MinimumVersion $moduleVersion -Force } } function Install-XrmToolingPowerShell { $moduleName = "Microsoft.Xrm.Tooling.CrmConnector.PowerShell" $moduleVersion = "3.3.0.899" $module = Get-Module -ListAvailable -Name $moduleName if (!($module.Version -ge $moduleVersion )) { Write-host "Module $moduleName version $moduleVersion or higher not found, installing now" Install-Module -Name $moduleName -MinimumVersion $moduleVersion -Force -AllowClobber } else { Write-host "Module $moduleName Found" Import-Module -Name $moduleName -MinimumVersion $moduleVersion -Force } } function Format-Json { <# .SYNOPSIS Prettifies JSON output. .DESCRIPTION Reformats a JSON string so the output looks better than what ConvertTo-Json outputs. .PARAMETER Json Required: [string] The JSON text to prettify. .PARAMETER Minify Optional: Returns the json string compressed. .PARAMETER Indentation Optional: The number of spaces (1..1024) to use for indentation. Defaults to 4. .PARAMETER AsArray Optional: If set, the output will be in the form of a string array, otherwise a single string is output. .EXAMPLE $json | ConvertTo-Json | Format-Json -Indentation 2 #> [CmdletBinding(DefaultParameterSetName = 'Prettify')] Param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] [string]$Json, [Parameter(ParameterSetName = 'Minify')] [switch]$Minify, [Parameter(ParameterSetName = 'Prettify')] [ValidateRange(1, 1024)] [int]$Indentation = 4, [Parameter(ParameterSetName = 'Prettify')] [switch]$AsArray ) if ($PSCmdlet.ParameterSetName -eq 'Minify') { return ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100 -Compress } # If the input JSON text has been created with ConvertTo-Json -Compress # then we first need to reconvert it without compression if ($Json -notmatch '\r?\n') { $Json = ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100 } $indent = 0 $regexUnlessQuoted = '(?=([^"]*"[^"]*")*[^"]*$)' $result = $Json -split '\r?\n' | ForEach-Object { # If the line contains a ] or } character, # we need to decrement the indentation level unless it is inside quotes. if ($_ -match "[}\]]$regexUnlessQuoted") { $indent = [Math]::Max($indent - $Indentation, 0) } # Replace all colon-space combinations by ": " unless it is inside quotes. $line = (' ' * $indent) + ($_.TrimStart() -replace ":\s+$regexUnlessQuoted", ': ') # If the line contains a [ or { character, # we need to increment the indentation level unless it is inside quotes. if ($_ -match "[\{\[]$regexUnlessQuoted") { $indent += $Indentation } $line } if ($AsArray) { return $result } return $result -Join [Environment]::NewLine } Function Invoke-Menu() { Param( [Parameter(Mandatory = $True)][String]$MenuTitle, [Parameter(Mandatory = $True)][array]$MenuOptions ) $MaxValue = $MenuOptions.count - 1 $Selection = 0 $EnterPressed = $False Clear-Host While ($EnterPressed -eq $False) { Write-Host "$MenuTitle" For ($i = 0; $i -le $MaxValue; $i++) { If ($i -eq $Selection) { Write-Host -BackgroundColor Cyan -ForegroundColor Black "[ $($MenuOptions[$i]) ]" } Else { Write-Host " $($MenuOptions[$i]) " } } $KeyInput = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown").virtualkeycode Switch ($KeyInput) { 13 { $EnterPressed = $True Return $Selection Clear-Host break } 38 { If ($Selection -eq 0) { $Selection = $MaxValue } Else { $Selection -= 1 } Clear-Host break } 40 { If ($Selection -eq $MaxValue) { $Selection = 0 } Else { $Selection += 1 } Clear-Host break } Default { Clear-Host } } } } function Copy-GitRepoFromTemplate { Write-Host "Select a folder to create a new git Repository for your Power Platform Project" try { $application = New-Object -ComObject Shell.Application $path = ($application.BrowseForFolder(0, 'Select a folder', 0)).Self.Path $global:projectLocation = "$path\$global:gitRepo" if (!(Test-Path -Path "$global:projectLocation") -and !($null -eq $path)) { Write-Host "Creating Project Folder" New-Item -Path $path -Name $global:gitRepo -ItemType Directory Copy-Item -Path (Join-Path $PSScriptRoot emptyProject.json) -Destination $global:projectLocation\$global:gitRepo.json $newProject = @([ordered]@{ID = $global:configfile.Projects.Count; Name = $global:gitRepo; ProjectLocation = "$global:projectLocation" }) $global:configfile.Projects += $newProject $global:configfile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json") $global:projectFile = Get-Content ("$global:projectLocation\$global:gitRepo.json") | ConvertFrom-Json Set-Location -Path "$global:projectLocation" $message = "Setting up PowerPlatformCICD locally" Write-Host $message Remove-Item -Path (Join-Path $PSScriptRoot ..\FrameworkTemplate\node_modules) -Recurse -Force -ErrorAction Ignore Copy-Item -Path (Join-Path $PSScriptRoot ..\FrameworkTemplate\*) -Destination $global:projectLocation\ -Recurse -Force $message = "Confirming Git User Details" Write-Host $message $GitUser = git config --global user.name $GitEmail = git config --global user.email If ($null -eq $GitUser) { $GitUser = Read-Host "Enter your name (to use when committing changes to Git)" git config --global user.name $GitUser } If ($null -eq $GitEmail) { $GitEmail = Read-Host "Enter your email address (to use when committing changes to Git)" git config --global user.email $GitEmail } Remove-Item .git -Recurse -Force -ErrorAction SilentlyContinue git init Write-Host "Updating Build.yaml ..." (Get-Content -Path $global:projectLocation\build.yaml) -replace "replaceRepo", $global:gitRepo | Set-Content -Path $global:projectLocation\build.yaml Write-Host "Rename PowerPlatformDevOps.sln to $global:gitRepo.sln" Rename-Item -Path $global:projectLocation\PowerPlatformDevOps.sln -NewName "$global:gitRepo.sln" $global:projectFile.gitRepo = $global:gitRepo $global:projectFile | ConvertTo-Json | Set-Content ("$global:projectLocation\$global:gitRepo.json") } else { Write-Warning "The Path $global:projectLocation already exists, please select a different path or project name" $continue = Read-Host -Prompt "Press [Enter] to Continue or [Q] to Quit" if (!$continue -eq 'Q') { } } } catch { } } function Add-GitRepo { do { $global:gitRepo = Read-Host -Prompt "Please enter a Name for the Git Repository you wish to Create" }until ($global:gitRepo -ne "") if (!(Test-Path $env:APPDATA\Microsoft.PowerPlatform.DevOps)) { New-Item -Path $env:APPDATA\Microsoft.PowerPlatform.Devops -ItemType Directory } if (!($global:configfile.PSobject.Properties.Project -contains "Name") -or !($global:configfile.Projects.Name.Contains($global:gitRepo))) { Copy-GitRepoFromTemplate pause } else { Write-Host "You already have a repo called $global:gitRepo, please select a different name" $global:gitRepo = "" Add-GitRepo } } function Select-GitRepo { if ($global:configfile.Projects.Count -gt 0) { $options = $global:configfile.Projects | ForEach-Object { "$($_.Name)" } do { $sel = Invoke-Menu -MenuTitle "---- Please Select your Project ------" -MenuOptions $options $selectedRepo = $global:configfile.Projects[$sel].Name } until ($selectedRepo -ne "") if (($global:configfile.Projects[$sel].PSobject.Properties.Name -contains "ProjectLocation")) { $global:projectFile = Get-Content ("$($global:configfile.Projects[$sel].ProjectLocation)\$selectedRepo.json") | ConvertFrom-Json $global:projectLocation = $global:configfile.Projects[$sel].ProjectLocation } else { $global:projectFile = Get-Content ("$env:APPDATA\Microsoft.PowerPlatform.Devops\$selectedRepo\$selectedRepo.json") | ConvertFrom-Json $global:projectLocation = $global:projectFile.ProjectLocation if (! (Test-Path -Path "$global:projectLocation\$selectedRepo.json")) { Copy-Item -Path "$env:APPDATA\Microsoft.PowerPlatform.Devops\$selectedRepo\$selectedRepo.json" -Destination " $global:projectLocation\" } $updatedProject = [ordered]@{ID = $global:configfile.Projects[$sel].ID; Name = $global:configfile.Projects[$sel].Name; ProjectLocation = $global:projectLocation } $global:configfile.Projects[$sel] = $updatedProject $global:configfile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json") $global:projectFile = Get-Content ("$global:projectLocation\$selectedRepo.json") | ConvertFrom-Json } Set-Location $global:projectLocation $global:projectTitle = $global:projectFile.gitRepo $global:gitRepo = $global:projectFile.gitRepo } else { Write-Host "You don't have any Projects set up, please Add a new one or Clone an existing Repo" pause } } function Clone-GitRepo { $regEx = '(http[s]?|[s]?ftp[s]?)(:\/\/)([^\s,]+)' do { $repoURL = Read-Host "Please enter the git clone URL" } until ($repoURL -ne "" -and $repoURL -match $regEx) $application = New-Object -ComObject Shell.Application $path = ($application.BrowseForFolder(0, "Select a folder to Clone your $selectedRepo Repo to", 0)).Self.Path $repoFinder = $repoURL -split "/" $selectedRepo = $repoFinder[$repoFinder.Count - 1].Replace('.git', '') $global:gitRepo = $selectedRepo Write-Host $selectedRepo Write-host $path Write-Host $repoURL . git clone $repoURL $path\$global:gitRepo $global:projectLocation = "$path\$selectedRepo" if (!(Test-Path -Path "$global:projectLocation\$selectedRepo.json")) { Copy-Item -Path (Join-Path $PSScriptRoot emptyProject.json) -Destination $global:projectLocation\$selectedRepo.json $global:projectFile = Get-Content ("$global:projectLocation\$selectedRepo.json") | ConvertFrom-Json $global:projectFile.gitRepo = $global:gitRepo $global:projectFile | ConvertTo-Json | Set-Content ("$global:projectLocation\$global:gitRepo.json") } $newProject = [ordered]@{ID = $global:configfile.Projects.Count; Name = $selectedRepo; ProjectLocation = $global:projectLocation } $global:configfile.Projects += $newProject $global:configfile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json") $global:projectFile = Get-Content ("$global:projectLocation\$global:gitRepo.json") | ConvertFrom-Json Set-Location $global:projectLocation $global:projectTitle = $global:projectFile.gitRepo pause } function Get-GitRepo { if (!(Test-Path $env:APPDATA\Microsoft.PowerPlatform.DevOps)) { New-Item -Path $env:APPDATA\Microsoft.PowerPlatform.Devops -ItemType Directory } $application = New-Object -ComObject Shell.Application $path = ($application.BrowseForFolder(0, "Select the location of your Existing Project", 0)).Self.Path $repoFinder = $path -split "\\" $selectedRepo = $repoFinder[$repoFinder.Count - 1] Write-Host $selectedRepo Write-Host $path\$selectedRepo.json if ((Test-Path -Path "$path\$selectedRepo.json")) { $global:projectLocation = "$path" $global:projectFile = Get-Content ("$path\$selectedRepo.json") | ConvertFrom-Json $newProject = [ordered]@{ID = $global:configfile.Projects.Count; Name = $selectedRepo; ProjectLocation = $global:projectLocation } $global:configfile.Projects += $newProject $global:configfile | ConvertTo-Json | Set-Content ("$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json") $global:gitRepo = $global:projectFile.gitRepo Set-Location $global:projectLocation } else { Write-Host "$path is not a valid Project Location, please Add a new one or Clone an existing Repo" pause } } |