From afb37ed474420ba4488a034c3ec4dde1dd1407fc Mon Sep 17 00:00:00 2001
From: Pim Simons <32359437+pim-simons@users.noreply.github.com>
Date: Fri, 14 Jan 2022 15:38:07 +0100
Subject: [PATCH] feat: Provide script to upload agreements into an Integration
 Account (#265)

Co-authored-by: Pim Simons <pim.simons@codit.eu>
---
 .../Arcus.Scripting.IntegrationAccount.psd1   | Bin 8066 -> 8152 bytes
 .../Arcus.Scripting.IntegrationAccount.psm1   |  38 +-
 ...Arcus.Scripting.IntegrationAccount.pssproj |   1 +
 .../Set-AzIntegrationAccountAgreements.ps1    | 117 +++
 .../Set-AzIntegrationAccountAssemblies.ps1    |   5 +-
 .../Set-AzIntegrationAccountCertificates.ps1  |   5 +-
 .../Scripts/Set-AzIntegrationAccountMaps.ps1  |   5 +-
 .../Set-AzIntegrationAccountPartners.ps1      |   9 +-
 .../Set-AzIntegrationAccountSchemas.ps1       |   5 +-
 ...cus.Scripting.IntegrationAccount.tests.ps1 | 187 +++++
 .../Arcus.Scripting.Tests.Integration.pssproj |   3 +
 .../Agreements/agreement1.json                | 150 ++++
 .../Agreements/agreement2.json                | 200 ++++++
 ...cus.Scripting.IntegrationAccount.tests.ps1 | 665 +++++++++++++++++-
 14 files changed, 1370 insertions(+), 20 deletions(-)
 create mode 100644 src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAgreements.ps1
 create mode 100644 src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement1.json
 create mode 100644 src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement2.json

diff --git a/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.psd1 b/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.psd1
index e23eda435e02593cd177c1d74e3b7cd74130ddad..a4c827a249c46b1fa7045c6d651221538adab57c 100644
GIT binary patch
delta 32
lcmZp&zhS>&is0l)0#5wt3`Gp7K$r`}c?>0+`vpJq0sypW3SIyJ

delta 12
Tcmca%-(<gGis0r~g70_%Ct(HG

diff --git a/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.psm1 b/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.psm1
index 2e8f5069..2cc91c5c 100644
--- a/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.psm1
+++ b/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.psm1
@@ -212,4 +212,40 @@ function Set-AzIntegrationAccountPartners {
     . $PSScriptRoot\Scripts\Set-AzIntegrationAccountPartners.ps1 -ResourceGroupName $ResourceGroupName -Name $Name -PartnerFilePath $PartnerFilePath -PartnersFolder $PartnersFolder -ArtifactsPrefix $ArtifactsPrefix
 }
 
-Export-ModuleMember -Function Set-AzIntegrationAccountPartners
\ No newline at end of file
+Export-ModuleMember -Function Set-AzIntegrationAccountPartners
+
+<#
+ .Synopsis
+  Upload/update a single, or multiple agreements into an Azure Integration Account.
+ 
+ .Description
+  Provide a file- or folder-path to upload/update a single or multiple agreements into an Integration Account.
+
+ .Parameter ResourceGroupName
+  The name of the Azure resource group where the Azure Integration Account is located.
+ 
+ .Parameter Name
+  The name of the Azure Integration Account into which the agreements are to be uploaded/updated.
+
+ .Parameter AgreementFilePath
+  The full path of a agreement that should be uploaded/updated.
+  
+ .Parameter AgreementsFolder
+  The path to a directory containing all agreements that should be uploaded/updated.
+
+ .Parameter ArtifactsPrefix
+  The prefix, if any, that should be added to the agreements before uploading/updating.
+#>
+function Set-AzIntegrationAccountAgreements {
+    param(
+        [Parameter(Mandatory = $true)][string] $ResourceGroupName = $(throw "Resource group name is required"),
+        [Parameter(Mandatory = $true)][string] $Name = $(throw "Name of the Integration Account is required"),
+        [parameter(Mandatory = $false)][string] $AgreementFilePath = $(if ($AgreementsFolder -eq '') { throw "Either the file path of a specific agreement or the file path of a folder containing multiple agreements is required, e.g.: -AgreementFilePath 'C:\Agreements\agreement.json' or -AgreementsFolder 'C:\Agreements'" }),
+        [parameter(Mandatory = $false)][string] $AgreementsFolder = $(if ($AgreementFilePath -eq '') { throw "Either the file path of a specific agreement or the file path of a folder containing multiple agreements is required, e.g.: -AgreementFilePath 'C:\Agreements\agreement.json' or -AgreementsFolder 'C:\Agreements'" }),
+        [Parameter(Mandatory = $false)][string] $ArtifactsPrefix = ''
+    )
+
+    . $PSScriptRoot\Scripts\Set-AzIntegrationAccountAgreements.ps1 -ResourceGroupName $ResourceGroupName -Name $Name -AgreementFilePath $AgreementFilePath -AgreementsFolder $AgreementsFolder -ArtifactsPrefix $ArtifactsPrefix
+}
+
+Export-ModuleMember -Function Set-AzIntegrationAccountAgreements
\ No newline at end of file
diff --git a/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.pssproj b/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.pssproj
index 85abff8f..5075a7a3 100644
--- a/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.pssproj
+++ b/src/Arcus.Scripting.IntegrationAccount/Arcus.Scripting.IntegrationAccount.pssproj
@@ -32,6 +32,7 @@
   <ItemGroup>
     <Compile Include="Arcus.Scripting.IntegrationAccount.psd1" />
     <Compile Include="Arcus.Scripting.IntegrationAccount.psm1" />
+    <Compile Include="Scripts\Set-AzIntegrationAccountAgreements.ps1" />
     <Compile Include="Scripts\Set-AzIntegrationAccountPartners.ps1" />
     <Compile Include="Scripts\Set-AzIntegrationAccountAssemblies.ps1" />
     <Compile Include="Scripts\Set-AzIntegrationAccountCertificates.ps1" />
diff --git a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAgreements.ps1 b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAgreements.ps1
new file mode 100644
index 00000000..a9fc0c0f
--- /dev/null
+++ b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAgreements.ps1
@@ -0,0 +1,117 @@
+Param(
+    [Parameter(Mandatory = $true)][string] $ResourceGroupName = $(throw "Resource group name is required"),
+    [Parameter(Mandatory = $true)][string] $Name = $(throw "Name of the Integration Account is required"),
+    [parameter(Mandatory = $false)][string] $AgreementFilePath = $(if ($AgreementsFolder -eq '') { throw "Either the file path of a specific agreement or the file path of a folder containing multiple agreements is required, e.g.: -AgreementFilePath 'C:\Agreements\agreement.json' or -AgreementsFolder 'C:\Agreements'" }),
+    [parameter(Mandatory = $false)][string] $AgreementsFolder = $(if ($AgreementFilePath -eq '') { throw "Either the file path of a specific agreement or the file path of a folder containing multiple agreements is required, e.g.: -AgreementFilePath 'C:\Agreements\agreement.json' or -AgreementsFolder 'C:\Agreements'" }),
+    [Parameter(Mandatory = $false)][string] $ArtifactsPrefix = ''
+)
+
+if ($AgreementFilePath -ne '' -and $AgreementsFolder -ne '') {
+    throw "Either the file path of a specific agreement or the file path of a folder containing multiple agreements is required, e.g.: -AgreementFilePath 'C:\Agreements\agreement.json' or -AgreementsFolder 'C:\Agreements'"
+}
+
+function UploadAgreement {
+    param(
+        [Parameter(Mandatory = $true)][System.IO.FileInfo] $Agreement
+    )
+
+    $agreementData = Get-Content -Raw -Path $Agreement.FullName | ConvertFrom-Json
+
+    $agreementName = $agreementData.name
+    if ($agreementName -eq $null -or $agreementName -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the agreement name is empty"
+    }
+
+    if ($ArtifactsPrefix -ne '') {
+        $agreementName = $ArtifactsPrefix + $agreementName
+    }
+    Write-Host "Uploading agreement '$agreementName' into the Integration Account '$Name'"
+
+    $agreementType = $agreementData.properties.agreementType
+    if ($agreementType -eq $null -or $agreementType -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the agreement type is empty"
+    }
+
+    $hostPartner = $agreementData.properties.hostPartner
+    if ($hostPartner -eq $null -or $hostPartner -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the host partner is empty"
+    }
+
+    $hostIdentityQualifier = $agreementData.properties.hostIdentity.qualifier
+    if ($hostIdentityQualifier -eq $null -or $hostIdentityQualifier -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the host identity qualifier is empty"
+    }
+
+    $hostIdentityQualifierValue = $agreementData.properties.hostIdentity.value
+    if ($hostIdentityQualifierValue -eq $null -or $hostIdentityQualifierValue -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the host identity value is empty"
+    }
+
+    $guestPartner = $agreementData.properties.guestPartner   
+    if ($guestPartner -eq $null -or $guestPartner -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the guest partner is empty"
+    }
+
+    $guestIdentityQualifier = $agreementData.properties.guestIdentity.qualifier
+    if ($guestIdentityQualifier -eq $null -or $guestIdentityQualifier -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the guest identity qualifier is empty"
+    }
+
+    $guestIdentityQualifierValue = $agreementData.properties.guestIdentity.value
+    if ($guestIdentityQualifierValue -eq $null -or $guestIdentityQualifierValue -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the guest identity value is empty"
+    }
+
+    $agreementContent = $agreementData.properties.content | ConvertTo-Json -Depth 20 -Compress
+    if ($agreementContent -eq $null -or $agreementContent -eq 'null' -or $agreementContent -eq '') {
+        throw "Cannot upload Agreement to Azure Integration Account '$Name' because the agreement content is empty"
+    }
+
+    $existingAgreement = $null
+    try {
+        Write-Verbose "Checking if the agreement '$agreementName' already exists in the Azure Integration Account '$Name'"
+        $existingAgreement = Get-AzIntegrationAccountAgreement -ResourceGroupName $ResourceGroupName -IntegrationAccount $Name -AgreementName $agreementName -ErrorAction Stop
+    }
+    catch {
+        if ($_.Exception.Message.Contains('could not be found')) {
+            Write-Verbose "No agreement '$agreementName' could not be found in Azure Integration Account '$Name'"
+        }
+        else {
+            throw $_.Exception
+        }
+    }
+        
+    try {
+        if ($existingAgreement -eq $null) {
+            Write-Verbose "Creating agreement '$agreementName' in Azure Integration Account '$Name'"
+            $createdAgreement = New-AzIntegrationAccountAgreement -ResourceGroupName $ResourceGroupName -IntegrationAccount $Name -AgreementName $agreementName -AgreementType $agreementType -HostPartner $hostPartner -HostIdentityQualifier $hostIdentityQualifier -HostIdentityQualifierValue $hostIdentityQualifierValue -GuestPartner $guestPartner -GuestIdentityQualifier $guestIdentityQualifier -GuestIdentityQualifierValue $guestIdentityQualifierValue -AgreementContent $agreementContent -ErrorAction Stop
+            Write-Verbose ($createdAgreement | Format-List -Force | Out-String)
+        }
+        else {
+            Write-Verbose "Updating agreement '$agreementName' in Azure Integration Account '$Name'"
+            $updatedAgreement = Set-AzIntegrationAccountAgreement -ResourceGroupName $ResourceGroupName -IntegrationAccount $Name -AgreementName $agreementName -AgreementType $agreementType -HostPartner $hostPartner -HostIdentityQualifier $hostIdentityQualifier -HostIdentityQualifierValue $hostIdentityQualifierValue -GuestPartner $guestPartner -GuestIdentityQualifier $guestIdentityQualifier -GuestIdentityQualifierValue $guestIdentityQualifierValue -AgreementContent $agreementContent -Force -ErrorAction Stop
+            Write-Verbose ($updatedAgreement | Format-List -Force | Out-String)
+        }
+        Write-Host "Agreement '$agreementName' has been uploaded into the Azure Integration Account '$Name'"
+    }
+    catch {
+        Write-Error "Failed to upload agreement '$agreementName' in Azure Integration Account '$Name': '$($_.Exception.Message)'"
+    }
+}
+
+$integrationAccount = Get-AzIntegrationAccount -ResourceGroupName $ResourceGroupName -Name $Name -ErrorAction SilentlyContinue
+if ($integrationAccount -eq $null) {
+    Write-Error "Unable to find the Azure Integration Account with name '$Name' in resource group '$ResourceGroupName'"
+}
+else {
+    if ($AgreementsFolder -ne '' -and $AgreementFilePath -eq '') {
+        foreach ($agreement in Get-ChildItem($AgreementsFolder) -File) {
+            UploadAgreement -Agreement $agreement
+            Write-Host '----------'
+        }
+    }
+    elseif ($AgreementsFolder -eq '' -and $AgreementFilePath -ne '') {
+        [System.IO.FileInfo]$agreement = New-Object System.IO.FileInfo($AgreementFilePath)
+        UploadAgreement -Agreement $agreement
+    }
+}
\ No newline at end of file
diff --git a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAssemblies.ps1 b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAssemblies.ps1
index 2f7aa8ae..7110ad2b 100644
--- a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAssemblies.ps1
+++ b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountAssemblies.ps1
@@ -20,11 +20,11 @@ function UploadAssembly {
     if ($ArtifactsPrefix -ne '') {
         $assemblyName = $ArtifactsPrefix + $assemblyName
     }
-    Write-Host "Uploading assembly '$assemblyName' into the Integration Account '$Name'"
+    Write-Host "Uploading assembly '$assemblyName' into the Azure Integration Account '$Name'"
 
     $existingAssembly = $null
     try {
-        Write-Verbose "Checking if the assembly '$assemblyName' already exists in the Integration Account '$Name'"
+        Write-Verbose "Checking if the assembly '$assemblyName' already exists in the Azure Integration Account '$Name'"
         $existingAssembly = Get-AzIntegrationAccountAssembly -ResourceGroupName $ResourceGroupName -IntegrationAccount $Name -Name $assemblyName -ErrorAction Stop
     }
     catch {
@@ -54,7 +54,6 @@ function UploadAssembly {
     }
 }
 
-# Verify if Integration Account can be found based on the given information
 $integrationAccount = Get-AzIntegrationAccount -ResourceGroupName $ResourceGroupName -Name $Name -ErrorAction SilentlyContinue
 if ($integrationAccount -eq $null) {
     Write-Error "Unable to find the Azure Integration Account with name '$Name' in resource group '$ResourceGroupName'"
diff --git a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountCertificates.ps1 b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountCertificates.ps1
index 200cbe91..3aaf38d7 100644
--- a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountCertificates.ps1
+++ b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountCertificates.ps1
@@ -32,11 +32,11 @@ function UploadCertificate {
     if ($ArtifactsPrefix -ne '') {
         $certificateName = $ArtifactsPrefix + $certificateName
     }
-    Write-Host "Uploading certificate '$certificateName' into the Integration Account '$Name'"
+    Write-Host "Uploading certificate '$certificateName' into the Azure Integration Account '$Name'"
 
     $existingCertificate = $null
     try {
-        Write-Verbose "Checking if the certificate '$certificateName' already exists in the Integration Account '$Name'"
+        Write-Verbose "Checking if the certificate '$certificateName' already exists in the Azure Integration Account '$Name'"
         $existingCertificate = Get-AzIntegrationAccountCertificate -ResourceGroupName $ResourceGroupName -IntegrationAccount $Name -CertificateName $certificateName -ErrorAction Stop
     }
     catch {
@@ -76,7 +76,6 @@ function UploadCertificate {
     }
 }
 
-# Verify if Integration Account can be found based on the given information
 $integrationAccount = Get-AzIntegrationAccount -ResourceGroupName $ResourceGroupName -Name $Name -ErrorAction SilentlyContinue
 if ($integrationAccount -eq $null) {
     Write-Error "Unable to find the Azure Integration Account with name '$Name' in resource group '$ResourceGroupName'"
diff --git a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountMaps.ps1 b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountMaps.ps1
index 22d885f4..87636187 100644
--- a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountMaps.ps1
+++ b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountMaps.ps1
@@ -25,11 +25,11 @@ function UploadMap {
     if ($ArtifactsPrefix -ne '') {
         $mapName = $ArtifactsPrefix + $mapName
     }
-    Write-Host "Uploading map '$mapName' into the Integration Account '$Name'"
+    Write-Host "Uploading map '$mapName' into the Azure Integration Account '$Name'"
 
     $existingMap = $null
     try {
-        Write-Verbose "Checking if the map '$mapName' already exists in the Integration Account '$Name'"
+        Write-Verbose "Checking if the map '$mapName' already exists in the Azure Integration Account '$Name'"
         $existingMap = Get-AzIntegrationAccountMap -ResourceGroupName $ResourceGroupName -Name $Name -MapName $mapName -ErrorAction Stop
     }
     catch {
@@ -59,7 +59,6 @@ function UploadMap {
     }
 }
 
-# Verify if Integration Account can be found based on the given information
 $integrationAccount = Get-AzIntegrationAccount -ResourceGroupName $ResourceGroupName -Name $Name -ErrorAction SilentlyContinue
 if ($integrationAccount -eq $null) {
     Write-Error "Unable to find the Azure Integration Account with name '$Name' in resource group '$ResourceGroupName'"
diff --git a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountPartners.ps1 b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountPartners.ps1
index 9f905c0f..4a62c026 100644
--- a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountPartners.ps1
+++ b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountPartners.ps1
@@ -19,13 +19,13 @@ function UploadPartner {
 
     $partnerName = $partnerData.name
     if ($partnerName -eq $null -or $partnerName -eq '') {
-        throw 'Partner name is empty'
+        throw "Cannot upload Partner to Azure Integration Account '$Name' because the partner name is empty"
     }
 
     if ($ArtifactsPrefix -ne '') {
         $partnerName = $ArtifactsPrefix + $partnerName
     }
-    Write-Host "Uploading partner '$partnerName' into the Integration Account '$Name'"
+    Write-Host "Uploading partner '$partnerName' into the Azure Integration Account '$Name'"
 
     $businessIdentities = $null
     foreach ($businessIdentity in $partnerData.properties.content.b2b.businessIdentities) {
@@ -36,12 +36,12 @@ function UploadPartner {
     }
 
     if ($businessIdentities.Count -eq 0) {
-        throw "At least one business identity must be supplied"
+        throw "Cannot upload Partner to Azure Integration Account '$Name' because at least one business identity must be supplied"
     }
 
     $existingPartner = $null
     try {
-        Write-Verbose "Checking if the partner '$partnerName' already exists in the Integration Account '$Name'"
+        Write-Verbose "Checking if the partner '$partnerName' already exists in the Azure Integration Account '$Name'"
         $existingPartner = Get-AzIntegrationAccountPartner -ResourceGroupName $ResourceGroupName -IntegrationAccount $Name -PartnerName $partnerName -ErrorAction Stop
     }
     catch {
@@ -71,7 +71,6 @@ function UploadPartner {
     }
 }
 
-# Verify if Integration Account can be found based on the given information
 $integrationAccount = Get-AzIntegrationAccount -ResourceGroupName $ResourceGroupName -Name $Name -ErrorAction SilentlyContinue
 if ($integrationAccount -eq $null) {
     Write-Error "Unable to find the Azure Integration Account with name '$Name' in resource group '$ResourceGroupName'"
diff --git a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountSchemas.ps1 b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountSchemas.ps1
index 10f00b37..582f01c2 100644
--- a/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountSchemas.ps1
+++ b/src/Arcus.Scripting.IntegrationAccount/Scripts/Set-AzIntegrationAccountSchemas.ps1
@@ -24,12 +24,12 @@ function UploadSchema {
     if ($ArtifactsPrefix -ne '') {
         $schemaName = $ArtifactsPrefix + $schemaName
     }
-    Write-Host "Uploading schema '$schemaName' into the Integration Account '$Name'"
+    Write-Host "Uploading schema '$schemaName' into the Azure Integration Account '$Name'"
 
     ## Check if the schema already exists
     $existingSchema = $null
     try {
-        Write-Verbose "Checking if the schema '$schemaName' already exists in the Integration Account '$Name'"
+        Write-Verbose "Checking if the schema '$schemaName' already exists in the Azure Integration Account '$Name'"
         $existingSchema = Get-AzIntegrationAccountSchema -ResourceGroupName $ResourceGroupName -Name $Name -SchemaName $schemaName -ErrorAction Stop
     }
     catch {
@@ -61,7 +61,6 @@ function UploadSchema {
     }
 }
 
-# Verify if Integration Account can be found based on the given information
 $integrationAccount = Get-AzIntegrationAccount -ResourceGroupName $ResourceGroupName -Name $Name -ErrorAction SilentlyContinue
 if ($integrationAccount -eq $null) {
     Write-Error "Unable to find the Azure Integration Account with name '$Name' in resource group '$ResourceGroupName'"
diff --git a/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.IntegrationAccount.tests.ps1 b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.IntegrationAccount.tests.ps1
index 51c05f74..611cd033 100644
--- a/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.IntegrationAccount.tests.ps1
+++ b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.IntegrationAccount.tests.ps1
@@ -906,5 +906,192 @@ InModuleScope Arcus.Scripting.IntegrationAccount {
                 }
             }
         }
+        Context "Uploading Agreements into an Azure Integration Account" {
+            It "Try to upload single agreement to unexisting Integration Account fails" {
+                # Arrange
+                $resourceGroupName = $config.Arcus.ResourceGroupName
+                $integrationAccountName = "unexisting-integration-account"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\agreement1.json"
+                $agreement = Get-ChildItem($agreementFilePath) -File
+
+                # Act
+                { Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreement.FullName -ErrorAction Stop} |
+                    Should -Throw
+            }
+            It "Create a single agreement in an Integration Account succeeds" {
+                # Arrange
+                $resourceGroupName = $config.Arcus.ResourceGroupName
+                $integrationAccountName = $config.Arcus.IntegrationAccount.Name
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\agreement1.json"
+                $agreement = Get-ChildItem($agreementFilePath) -File
+                $agreementData = Get-Content -Raw -Path $agreement.FullName | ConvertFrom-Json
+                $expectedAgreementName = $agreementData.name
+                $executionDateTime = (Get-Date).ToUniversalTime()
+
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -BusinessIdentities @("1", "12345")
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -BusinessIdentities @("1", "98765")
+
+                try {
+                    # Act
+                    Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreement.FullName
+
+                    # Assert
+                    $actual = Get-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName
+                    $actual | Should -Not -BeNullOrEmpty 
+                    $actual.CreatedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss") | Should -BeIn @($actual.ChangedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss"), $actual.ChangedTime.ToUniversalTime().AddSeconds(-1).ToString("yyyy-MM-ddTHH:mm:ss"))
+                    $actual.CreatedTime | Should -BeGreaterOrEqual $executionDateTime
+
+                } finally {
+                    Remove-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName -Force
+                    Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -Force
+                    Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -Force
+                }
+            }
+            It "Update a single agreement in an Integration Account succeeds" {
+                # Arrange
+                $resourceGroupName = $config.Arcus.ResourceGroupName
+                $integrationAccountName = $config.Arcus.IntegrationAccount.Name
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\agreement1.json"
+                $agreement = Get-ChildItem($agreementFilePath) -File
+                $executionDateTime = (Get-Date).ToUniversalTime()
+                $agreementData = Get-Content -Raw -Path $agreement.FullName | ConvertFrom-Json
+                $expectedAgreementName = $agreementData.name
+                $agreementType = $agreementData.properties.agreementType
+                $hostPartner = $agreementData.properties.hostPartner
+                $hostIdentityQualifier = $agreementData.properties.hostIdentity.qualifier
+                $hostIdentityQualifierValue = $agreementData.properties.hostIdentity.value
+                $guestPartner = $agreementData.properties.guestPartner    
+                $guestIdentityQualifier = $agreementData.properties.guestIdentity.qualifier
+                $guestIdentityQualifierValue = $agreementData.properties.guestIdentity.value
+                $agreementData.properties.content.aS2.receiveAgreement.protocolSettings.messageConnectionSettings.ignoreCertificateNameMismatch = 'True'
+                $agreementContent = $agreementData.properties.content | ConvertTo-Json -Depth 20 -Compress
+
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -BusinessIdentities @("1", "12345")
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -BusinessIdentities @("1", "98765")
+
+                $existingAgreement = New-AzIntegrationAccountAgreement -ResourceGroupName $ResourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName -AgreementType $agreementType -HostPartner $hostPartner -HostIdentityQualifier $hostIdentityQualifier -HostIdentityQualifierValue $hostIdentityQualifierValue -GuestPartner $guestPartner -GuestIdentityQualifier $guestIdentityQualifier -GuestIdentityQualifierValue $guestIdentityQualifierValue -AgreementContent $agreementContent -ErrorAction Stop
+
+                try {
+                    # Act
+                    Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreement.FullName
+
+                    # Assert
+                    $actual = Get-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName
+                    $actual | Should -Not -BeNullOrEmpty
+                    $actual.CreatedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss") | Should -BeIn ($existingAgreement.ChangedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss"), $existingAgreement.ChangedTime.ToUniversalTime().AddSeconds(-1).ToString("yyyy-MM-ddTHH:mm:ss"))
+                    $actual.ChangedTime.ToUniversalTime() | Should -BeGreaterOrEqual $executionDateTime
+                    $actual.content.aS2.receiveAgreement.protocolSettings.messageConnectionSettings.ignoreCertificateNameMismatch | Should -Be 'False'
+                    $existingAgreement.CreatedTime.ToUniversalTime() | Should -BeLessOrEqual $actual.ChangedTime.ToUniversalTime()
+
+                } finally {
+                    Remove-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName -Force
+                    Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -Force
+                    Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -Force
+                }
+            }
+            It "Create a single agreement, with prefix, in an Integration Account succeeds" {
+                # Arrange
+                $resourceGroupName = $config.Arcus.ResourceGroupName
+                $integrationAccountName = $config.Arcus.IntegrationAccount.Name
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\agreement1.json"
+                $agreement = Get-ChildItem($agreementFilePath) -File
+                $agreementData = Get-Content -Raw -Path $agreement.FullName | ConvertFrom-Json
+                $artifactsPrefix = "dev-"
+                $expectedAgreementName = $artifactsPrefix + $agreementData.name
+                $executionDateTime = (Get-Date).ToUniversalTime()
+
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -BusinessIdentities @("1", "12345")
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -BusinessIdentities @("1", "98765")
+
+                try {
+                    # Act
+                    Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreement.FullName -ArtifactsPrefix $artifactsPrefix
+
+                    # Assert
+                    $actual = Get-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName
+                    $actual | Should -Not -BeNullOrEmpty
+                    $actual.CreatedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss") | Should -BeIn ($actual.ChangedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss"), $actual.ChangedTime.ToUniversalTime().AddSeconds(-1).ToString("yyyy-MM-ddTHH:mm:ss"))
+                    $actual.CreatedTime | Should -BeGreaterOrEqual $executionDateTime
+
+                } finally {
+                    Remove-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName -Force
+                    Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -Force
+                    Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -Force
+                }
+            }
+            It "Create multiple agreements located in a folder in an Integration Account succeeds" {
+                # Arrange
+                $resourceGroupName = $config.Arcus.ResourceGroupName
+                $integrationAccountName = $config.Arcus.IntegrationAccount.Name
+                $agreementsFolder = "$PSScriptRoot\Files\IntegrationAccount\Agreements"
+                $executionDateTime = (Get-Date).ToUniversalTime()
+
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -BusinessIdentities @("1", "12345")
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -BusinessIdentities @("1", "98765")
+
+                try {
+                    # Act
+                    Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementsFolder $agreementsFolder
+
+                    # Assert
+                    foreach ($agreement in Get-ChildItem($agreementsFolder) -File) {
+                        $agreementData = Get-Content -Raw -Path $agreement.FullName | ConvertFrom-Json
+                        $expectedAgreementName = $agreementData.name
+                        
+                        $actual = Get-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName
+                        $actual | Should -Not -BeNullOrEmpty
+                        $actual.CreatedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss") | Should -BeIn ($actual.ChangedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss"), $actual.ChangedTime.ToUniversalTime().AddSeconds(-1).ToString("yyyy-MM-ddTHH:mm:ss"))
+                        $actual.CreatedTime | Should -BeGreaterOrEqual $executionDateTime
+                    }
+
+                } finally {
+                    foreach ($agreement in Get-ChildItem($agreementsFolder) -File) {
+                        $agreementData = Get-Content -Raw -Path $agreement.FullName | ConvertFrom-Json
+                        $expectedAgreementName = $agreementData.name
+                        
+                        Remove-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName -Force
+                        Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -Force
+                        Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -Force
+                    }
+                }
+            }
+            It "Create multiple agreements, with prefix, located in a folder in an Integration Account succeeds" {
+                # Arrange
+                $resourceGroupName = $config.Arcus.ResourceGroupName
+                $integrationAccountName = $config.Arcus.IntegrationAccount.Name
+                $agreementsFolder = "$PSScriptRoot\Files\IntegrationAccount\Agreements"
+                $artifactsPrefix = "dev-"
+                $executionDateTime = (Get-Date).ToUniversalTime()
+
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -BusinessIdentities @("1", "12345")
+                New-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -BusinessIdentities @("1", "98765")
+
+                try {
+                    # Act
+                    Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementsFolder $agreementsFolder -ArtifactsPrefix $artifactsPrefix
+
+                    # Assert
+                    foreach ($agreement in Get-ChildItem($agreementsFolder) -File) {
+                        $agreementData = Get-Content -Raw -Path $agreement.FullName | ConvertFrom-Json
+                        $expectedAgreementName = $artifactsPrefix + $agreementData.name
+                        
+                        $actual = Get-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName
+                        $actual | Should -Not -BeNullOrEmpty
+                        $actual.CreatedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss") | Should -BeIn ($actual.ChangedTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss"), $actual.ChangedTime.ToUniversalTime().AddSeconds(-1).ToString("yyyy-MM-ddTHH:mm:ss"))
+                        $actual.CreatedTime | Should -BeGreaterOrEqual $executionDateTime
+                    }
+
+                } finally {
+                    foreach ($agreement in Get-ChildItem($agreementsFolder) -File) {
+                        $agreementData = Get-Content -Raw -Path $agreement.FullName | ConvertFrom-Json
+                        $expectedAgreementName = $artifactsPrefix + $agreementData.name
+                        
+                        Remove-AzIntegrationAccountAgreement -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -AgreementName $expectedAgreementName -Force
+                        Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner1 -Force
+                        Remove-AzIntegrationAccountPartner -ResourceGroupName $resourceGroupName -IntegrationAccountName $integrationAccountName -PartnerName Partner2 -Force
+                    }
+                }
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj
index c4e6bd39..e6f2ba1a 100644
--- a/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj
+++ b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj
@@ -53,6 +53,7 @@
     <Folder Include="Files\IntegrationAccount\Maps\" />
     <Folder Include="Files\IntegrationAccount\Assemblies\" />
     <Folder Include="Files\IntegrationAccount\Certificates\" />
+    <Folder Include="Files\IntegrationAccount\Agreements\" />
     <Folder Include="Files\IntegrationAccount\Partners\" />
     <Folder Include="Files\IntegrationAccount\Schemas\" />
     <Folder Include="Files\IntegrationAccount\Schemas\Common\" />
@@ -87,6 +88,8 @@
     <Content Include="Files\arm-template-inline.json" />
     <Content Include="Files\arm-template-inline-value.json" />
     <Content Include="Files\arm-template-inline-org.json" />
+    <Content Include="Files\IntegrationAccount\Agreements\agreement1.json" />
+    <Content Include="Files\IntegrationAccount\Agreements\agreement2.json" />
     <Content Include="Files\IntegrationAccount\Assemblies\AssemblyThatDoesSomething.dll" />
     <Content Include="Files\IntegrationAccount\Assemblies\AssemblyThatDoesSomethingElse.dll" />
     <Content Include="Files\IntegrationAccount\Certificates\certificate1.cer" />
diff --git a/src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement1.json b/src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement1.json
new file mode 100644
index 00000000..9a4ca713
--- /dev/null
+++ b/src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement1.json
@@ -0,0 +1,150 @@
+{
+  "name": "Agreement1",
+  "properties": {
+    "hostPartner": "Partner1",
+    "guestPartner": "Partner2",
+    "hostIdentity": {
+      "qualifier": "1",
+      "value": "12345"
+    },
+    "guestIdentity": {
+      "qualifier": "1",
+      "value": "98765"
+    },
+    "agreementType": "AS2",
+    "content": {
+      "aS2": {
+        "receiveAgreement": {
+          "protocolSettings": {
+            "messageConnectionSettings": {
+              "ignoreCertificateNameMismatch": false,
+              "supportHttpStatusCodeContinue": true,
+              "keepHttpConnectionAlive": true,
+              "unfoldHttpHeaders": true
+            },
+            "acknowledgementConnectionSettings": {
+              "ignoreCertificateNameMismatch": false,
+              "supportHttpStatusCodeContinue": false,
+              "keepHttpConnectionAlive": false,
+              "unfoldHttpHeaders": false
+            },
+            "mdnSettings": {
+              "needMDN": false,
+              "signMDN": false,
+              "sendMDNAsynchronously": false,
+              "dispositionNotificationTo": "http://localhost",
+              "signOutboundMDNIfOptional": false,
+              "sendInboundMDNToMessageBox": true,
+              "micHashingAlgorithm": "SHA1"
+            },
+            "securitySettings": {
+              "overrideGroupSigningCertificate": false,
+              "enableNRRForInboundEncodedMessages": false,
+              "enableNRRForInboundDecodedMessages": false,
+              "enableNRRForOutboundMDN": false,
+              "enableNRRForOutboundEncodedMessages": false,
+              "enableNRRForOutboundDecodedMessages": false,
+              "enableNRRForInboundMDN": false
+            },
+            "validationSettings": {
+              "overrideMessageProperties": false,
+              "encryptMessage": false,
+              "signMessage": false,
+              "compressMessage": false,
+              "checkDuplicateMessage": false,
+              "interchangeDuplicatesValidityDays": 5,
+              "checkCertificateRevocationListOnSend": false,
+              "checkCertificateRevocationListOnReceive": false,
+              "encryptionAlgorithm": "DES3",
+              "signingAlgorithm": "Default"
+            },
+            "envelopeSettings": {
+              "messageContentType": "text/plain",
+              "transmitFileNameInMimeHeader": false,
+              "fileNameTemplate": "%FILE().ReceivedFileName%",
+              "suspendMessageOnFileNameGenerationError": true,
+              "autogenerateFileName": false
+            },
+            "errorSettings": {
+              "suspendDuplicateMessage": false,
+              "resendIfMDNNotReceived": false
+            }
+          },
+          "senderBusinessIdentity": {
+            "qualifier": "1",
+            "value": "9876"
+          },
+          "receiverBusinessIdentity": {
+            "qualifier": "1",
+            "value": "1234"
+          }
+        },
+        "sendAgreement": {
+          "protocolSettings": {
+            "messageConnectionSettings": {
+              "ignoreCertificateNameMismatch": false,
+              "supportHttpStatusCodeContinue": true,
+              "keepHttpConnectionAlive": true,
+              "unfoldHttpHeaders": true
+            },
+            "acknowledgementConnectionSettings": {
+              "ignoreCertificateNameMismatch": false,
+              "supportHttpStatusCodeContinue": false,
+              "keepHttpConnectionAlive": false,
+              "unfoldHttpHeaders": false
+            },
+            "mdnSettings": {
+              "needMDN": false,
+              "signMDN": false,
+              "sendMDNAsynchronously": false,
+              "dispositionNotificationTo": "http://localhost",
+              "signOutboundMDNIfOptional": false,
+              "sendInboundMDNToMessageBox": true,
+              "micHashingAlgorithm": "SHA1"
+            },
+            "securitySettings": {
+              "overrideGroupSigningCertificate": false,
+              "enableNRRForInboundEncodedMessages": false,
+              "enableNRRForInboundDecodedMessages": false,
+              "enableNRRForOutboundMDN": false,
+              "enableNRRForOutboundEncodedMessages": false,
+              "enableNRRForOutboundDecodedMessages": false,
+              "enableNRRForInboundMDN": false
+            },
+            "validationSettings": {
+              "overrideMessageProperties": false,
+              "encryptMessage": false,
+              "signMessage": false,
+              "compressMessage": false,
+              "checkDuplicateMessage": false,
+              "interchangeDuplicatesValidityDays": 5,
+              "checkCertificateRevocationListOnSend": false,
+              "checkCertificateRevocationListOnReceive": false,
+              "encryptionAlgorithm": "DES3",
+              "signingAlgorithm": "Default"
+            },
+            "envelopeSettings": {
+              "messageContentType": "text/plain",
+              "transmitFileNameInMimeHeader": false,
+              "fileNameTemplate": "%FILE().ReceivedFileName%",
+              "suspendMessageOnFileNameGenerationError": true,
+              "autogenerateFileName": false
+            },
+            "errorSettings": {
+              "suspendDuplicateMessage": false,
+              "resendIfMDNNotReceived": false
+            }
+          },
+          "senderBusinessIdentity": {
+            "qualifier": "1",
+            "value": "1234"
+          },
+          "receiverBusinessIdentity": {
+            "qualifier": "1",
+            "value": "9876"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement2.json b/src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement2.json
new file mode 100644
index 00000000..31f6777d
--- /dev/null
+++ b/src/Arcus.Scripting.Tests.Integration/Files/IntegrationAccount/Agreements/agreement2.json
@@ -0,0 +1,200 @@
+{
+  "name": "Agreement2",
+  "properties": {
+    "hostPartner": "Partner1",
+    "guestPartner": "Partner2",
+    "hostIdentity": {
+      "qualifier": "1",
+      "value": "12345"
+    },
+    "guestIdentity": {
+      "qualifier": "1",
+      "value": "98765"
+    },
+    "agreementType": "X12",
+    "content": {
+      "x12": {
+        "receiveAgreement": {
+          "protocolSettings": {
+            "validationSettings": {
+              "validateCharacterSet": true,
+              "checkDuplicateInterchangeControlNumber": false,
+              "interchangeControlNumberValidityDays": 30,
+              "checkDuplicateGroupControlNumber": false,
+              "checkDuplicateTransactionSetControlNumber": false,
+              "validateEDITypes": true,
+              "validateXSDTypes": false,
+              "allowLeadingAndTrailingSpacesAndZeroes": false,
+              "trimLeadingAndTrailingSpacesAndZeroes": false,
+              "trailingSeparatorPolicy": "NotAllowed"
+            },
+            "framingSettings": {
+              "dataElementSeparator": 42,
+              "componentSeparator": 58,
+              "replaceSeparatorsInPayload": false,
+              "replaceCharacter": 36,
+              "segmentTerminator": 126,
+              "characterSet": "UTF8",
+              "segmentTerminatorSuffix": "None"
+            },
+            "envelopeSettings": {
+              "controlStandardsId": 85,
+              "useControlStandardsIdAsRepetitionCharacter": false,
+              "senderApplicationId": "BTS-SENDER",
+              "receiverApplicationId": "RECEIVE-APP",
+              "controlVersionNumber": "00401",
+              "interchangeControlNumberLowerBound": 1,
+              "interchangeControlNumberUpperBound": 999999999,
+              "rolloverInterchangeControlNumber": true,
+              "enableDefaultGroupHeaders": true,
+              "groupControlNumberLowerBound": 1,
+              "groupControlNumberUpperBound": 999999999,
+              "rolloverGroupControlNumber": true,
+              "groupHeaderAgencyCode": "T",
+              "groupHeaderVersion": "00401",
+              "transactionSetControlNumberLowerBound": 1,
+              "transactionSetControlNumberUpperBound": 999999999,
+              "rolloverTransactionSetControlNumber": true,
+              "overwriteExistingTransactionSetControlNumber": true,
+              "groupHeaderDateFormat": "CCYYMMDD",
+              "groupHeaderTimeFormat": "HHMM",
+              "usageIndicator": "Test"
+            },
+            "acknowledgementSettings": {
+              "needTechnicalAcknowledgement": false,
+              "batchTechnicalAcknowledgements": true,
+              "needFunctionalAcknowledgement": false,
+              "functionalAcknowledgementVersion": "00401",
+              "batchFunctionalAcknowledgements": true,
+              "needImplementationAcknowledgement": false,
+              "batchImplementationAcknowledgements": false,
+              "needLoopForValidMessages": false,
+              "sendSynchronousAcknowledgement": true,
+              "acknowledgementControlNumberLowerBound": 1,
+              "acknowledgementControlNumberUpperBound": 999999999,
+              "rolloverAcknowledgementControlNumber": true
+            },
+            "messageFilter": {
+              "messageFilterType": "Exclude"
+            },
+            "securitySettings": {
+              "authorizationQualifier": "00",
+              "securityQualifier": "00"
+            },
+            "processingSettings": {
+              "maskSecurityInfo": true,
+              "convertImpliedDecimal": false,
+              "preserveInterchange": false,
+              "suspendInterchangeOnError": false,
+              "createEmptyXmlTagsForTrailingSeparators": true,
+              "useDotAsDecimalSeparator": false
+            },
+            "envelopeOverrides": [],
+            "validationOverrides": [],
+            "messageFilterList": [],
+            "schemaReferences": [],
+            "x12DelimiterOverrides": []
+          },
+          "senderBusinessIdentity": {
+            "qualifier": "1",
+            "value": "9876"
+          },
+          "receiverBusinessIdentity": {
+            "qualifier": "1",
+            "value": "1234"
+          }
+        },
+        "sendAgreement": {
+          "protocolSettings": {
+            "validationSettings": {
+              "validateCharacterSet": true,
+              "checkDuplicateInterchangeControlNumber": false,
+              "interchangeControlNumberValidityDays": 30,
+              "checkDuplicateGroupControlNumber": false,
+              "checkDuplicateTransactionSetControlNumber": false,
+              "validateEDITypes": true,
+              "validateXSDTypes": false,
+              "allowLeadingAndTrailingSpacesAndZeroes": false,
+              "trimLeadingAndTrailingSpacesAndZeroes": false,
+              "trailingSeparatorPolicy": "NotAllowed"
+            },
+            "framingSettings": {
+              "dataElementSeparator": 42,
+              "componentSeparator": 58,
+              "replaceSeparatorsInPayload": false,
+              "replaceCharacter": 36,
+              "segmentTerminator": 126,
+              "characterSet": "UTF8",
+              "segmentTerminatorSuffix": "None"
+            },
+            "envelopeSettings": {
+              "controlStandardsId": 85,
+              "useControlStandardsIdAsRepetitionCharacter": false,
+              "senderApplicationId": "BTS-SENDER",
+              "receiverApplicationId": "RECEIVE-APP",
+              "controlVersionNumber": "00401",
+              "interchangeControlNumberLowerBound": 1,
+              "interchangeControlNumberUpperBound": 999999999,
+              "rolloverInterchangeControlNumber": true,
+              "enableDefaultGroupHeaders": true,
+              "groupControlNumberLowerBound": 1,
+              "groupControlNumberUpperBound": 999999999,
+              "rolloverGroupControlNumber": true,
+              "groupHeaderAgencyCode": "T",
+              "groupHeaderVersion": "00401",
+              "transactionSetControlNumberLowerBound": 1,
+              "transactionSetControlNumberUpperBound": 999999999,
+              "rolloverTransactionSetControlNumber": true,
+              "overwriteExistingTransactionSetControlNumber": true,
+              "groupHeaderDateFormat": "CCYYMMDD",
+              "groupHeaderTimeFormat": "HHMM",
+              "usageIndicator": "Test"
+            },
+            "acknowledgementSettings": {
+              "needTechnicalAcknowledgement": false,
+              "batchTechnicalAcknowledgements": true,
+              "needFunctionalAcknowledgement": false,
+              "functionalAcknowledgementVersion": "00401",
+              "batchFunctionalAcknowledgements": true,
+              "needImplementationAcknowledgement": false,
+              "batchImplementationAcknowledgements": false,
+              "needLoopForValidMessages": false,
+              "sendSynchronousAcknowledgement": true,
+              "acknowledgementControlNumberLowerBound": 1,
+              "acknowledgementControlNumberUpperBound": 999999999,
+              "rolloverAcknowledgementControlNumber": true
+            },
+            "messageFilter": {
+              "messageFilterType": "Exclude"
+            },
+            "securitySettings": {
+              "authorizationQualifier": "00",
+              "securityQualifier": "00"
+            },
+            "processingSettings": {
+              "maskSecurityInfo": true,
+              "convertImpliedDecimal": false,
+              "preserveInterchange": false,
+              "suspendInterchangeOnError": false,
+              "createEmptyXmlTagsForTrailingSeparators": true,
+              "useDotAsDecimalSeparator": false
+            },
+            "envelopeOverrides": [],
+            "validationOverrides": [],
+            "messageFilterList": [],
+            "schemaReferences": [],
+            "x12DelimiterOverrides": []
+          },
+          "senderBusinessIdentity": {
+            "qualifier": "1",
+            "value": "1234"
+          },
+          "receiverBusinessIdentity": {
+            "qualifier": "1",
+            "value": "9876"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/Arcus.Scripting.Tests.Unit/Arcus.Scripting.IntegrationAccount.tests.ps1 b/src/Arcus.Scripting.Tests.Unit/Arcus.Scripting.IntegrationAccount.tests.ps1
index fa780e44..a10566f6 100644
--- a/src/Arcus.Scripting.Tests.Unit/Arcus.Scripting.IntegrationAccount.tests.ps1
+++ b/src/Arcus.Scripting.Tests.Unit/Arcus.Scripting.IntegrationAccount.tests.ps1
@@ -1004,7 +1004,7 @@ InModuleScope Arcus.Scripting.IntegrationAccount {
                 # Act
                 { 
                    Set-AzIntegrationAccountPartners -ResourceGroupName $resourceGroupName -Name $integrationAccountName -PartnerFilePath $partnerFilePath
-                } | Should -Throw -ExpectedMessage "Partner name is empty"
+                } | Should -Throw -ExpectedMessage "Cannot upload Partner to Azure Integration Account '$integrationAccountName' because the partner name is empty"
 
                 # Assert
                 Assert-VerifiableMock
@@ -1032,7 +1032,7 @@ InModuleScope Arcus.Scripting.IntegrationAccount {
                 # Act
                 { 
                    Set-AzIntegrationAccountPartners -ResourceGroupName $resourceGroupName -Name $integrationAccountName -PartnerFilePath $partnerFilePath
-                } | Should -Throw -ExpectedMessage "At least one business identity must be supplied"
+                } | Should -Throw -ExpectedMessage "Cannot upload Partner to Azure Integration Account '$integrationAccountName' because at least one business identity must be supplied"
 
                 # Assert
                 Assert-VerifiableMock
@@ -1264,5 +1264,666 @@ InModuleScope Arcus.Scripting.IntegrationAccount {
                 Assert-MockCalled New-AzIntegrationAccountPartner -Times 0
             }
         }
+        Context "Azure Integration Account Agreements" {
+            It "Providing both agreementFilePath and agreementsFolder should fail" {
+                # Arrange
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\Agreement1.json"
+                $agreementsFolder = "$PSScriptRoot\Files\IntegrationAccount\Agreements\"
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath -AgreementsFolder $agreementsFolder
+                } | Should -Throw -ExpectedMessage "Either the file path of a specific agreement or the file path of a folder containing multiple agreements is required, e.g.: -AgreementFilePath 'C:\Agreements\agreement.json' or -AgreementsFolder 'C:\Agreements'"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Providing neither a agreementFilePath and agreementsFolder should fail" {
+                # Arrange
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName
+                } | Should -Throw -ExpectedMessage "Either the file path of a specific agreement or the file path of a folder containing multiple agreements is required, e.g.: -AgreementFilePath 'C:\Agreements\agreement.json' or -AgreementsFolder 'C:\Agreements'"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Agreement Name should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+                    return [pscustomobject] @{
+                        properties = [pscustomobject] @{
+                            agreementType = 'AS2';
+                            hostPartner = 'Partner1';
+                            guestPartner = 'Partner2';
+                            hostIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '12345';
+                            }
+                            guestIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '98765';
+                            }
+                            content = [pscustomobject] @{
+                                aS2 = [pscustomobject] @{}
+                            }
+                        }
+                    } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the agreement name is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Agreement Type should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+                    return [pscustomobject] @{
+                        name = $agreementName;
+                        properties = [pscustomobject] @{
+                            hostPartner = 'Partner1';
+                            guestPartner = 'Partner2';
+                            hostIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '12345';
+                            }
+                            guestIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '98765';
+                            }
+                            content = [pscustomobject] @{
+                                aS2 = [pscustomobject] @{}
+                            }
+                        }
+                    } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the agreement type is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Host Partner should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+	                return [pscustomobject] @{
+		                name = $agreementName;
+		                properties = [pscustomobject] @{
+			                agreementType = 'AS2';
+			                guestPartner = 'Partner2';
+			                hostIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '12345';
+			                }
+			                guestIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '98765';
+			                }
+			                content = [pscustomobject] @{
+				                aS2 = [pscustomobject] @{}
+			                }
+		                }
+	                } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the host partner is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Host Identity Qualifier should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+	                return [pscustomobject] @{
+		                name = $agreementName;
+		                properties = [pscustomobject] @{
+			                agreementType = 'AS2';
+			                hostPartner = 'Partner1';
+			                guestPartner = 'Partner2';
+			                hostIdentity = [pscustomobject] @{
+				                value = '12345';
+			                }
+			                guestIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '98765';
+			                }
+			                content = [pscustomobject] @{
+				                aS2 = [pscustomobject] @{}
+			                }
+		                }
+	                } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the host identity qualifier is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Host Identity Value should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+	                return [pscustomobject] @{
+		                name = $agreementName;
+		                properties = [pscustomobject] @{
+			                agreementType = 'AS2';
+			                hostPartner = 'Partner1';
+			                guestPartner = 'Partner2';
+			                hostIdentity = [pscustomobject] @{
+				                qualifier = '1';
+			                }
+			                guestIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '98765';
+			                }
+			                content = [pscustomobject] @{
+				                aS2 = [pscustomobject] @{}
+			                }
+		                }
+	                } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the host identity value is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Guest Partner should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+	                return [pscustomobject] @{
+		                name = $agreementName;
+		                properties = [pscustomobject] @{
+			                agreementType = 'AS2';
+			                hostPartner = 'Partner1';
+			                hostIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '12345';
+			                }
+			                guestIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '98765';
+			                }
+			                content = [pscustomobject] @{
+				                aS2 = [pscustomobject] @{}
+			                }
+		                }
+	                } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the guest partner is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Guest Identity Qualifier should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+	                return [pscustomobject] @{
+		                name = $agreementName;
+		                properties = [pscustomobject] @{
+			                agreementType = 'AS2';
+			                hostPartner = 'Partner1';
+			                guestPartner = 'Partner2';
+			                hostIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '12345';
+			                }
+			                guestIdentity = [pscustomobject] @{
+				                value = '98765';
+			                }
+			                content = [pscustomobject] @{
+				                aS2 = [pscustomobject] @{}
+			                }
+		                }
+	                } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the guest identity qualifier is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Guest Identity Value should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+	                return [pscustomobject] @{
+		                name = $agreementName;
+		                properties = [pscustomobject] @{
+			                agreementType = 'AS2';
+			                hostPartner = 'Partner1';
+			                guestPartner = 'Partner2';
+			                hostIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '12345';
+			                }
+			                guestIdentity = [pscustomobject] @{
+				                qualifier = '1';
+			                }
+			                content = [pscustomobject] @{
+				                aS2 = [pscustomobject] @{}
+			                }
+		                }
+	                } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the guest identity value is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Not Providing an Agreement Content should fail" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+	                return [pscustomobject] @{
+		                name = $agreementName;
+		                properties = [pscustomobject] @{
+			                agreementType = 'AS2';
+			                hostPartner = 'Partner1';
+			                guestPartner = 'Partner2';
+			                hostIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '12345';
+			                }
+			                guestIdentity = [pscustomobject] @{
+				                qualifier = '1';
+				                value = '98765';
+			                }
+		                }
+	                } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                # Act
+                { 
+                   Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath
+                } | Should -Throw -ExpectedMessage "Cannot upload Agreement to Azure Integration Account '$integrationAccountName' because the agreement content is empty"
+
+                # Assert
+                Assert-VerifiableMock
+            }
+            It "Providing only the agreementFilePath to create an agreement is OK" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+                $agreementName = 'Dummy_New_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+                $agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+                    return [pscustomobject] @{
+                        name = 'Agreement';
+                        properties = [pscustomobject] @{
+                            hostPartner = 'Partner1';
+                            guestPartner = 'Partner2';
+                            hostIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '12345';
+                            }
+                            guestIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '98765';
+                            }
+                            agreementType = 'AS2';
+                                content = [pscustomobject] @{
+                                    aS2 = [pscustomobject] @{}
+                            }
+                        }
+                    } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+                
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccountAgreement {
+                    return $null
+                } -Verifiable
+
+                Mock Set-AzIntegrationAccountAgreement {
+                    return $null
+                }
+
+                Mock New-AzIntegrationAccountAgreement {
+                    return [pscustomobject]@{ Id = $agreementResourceId; Name = $agreementName; Type = 'Microsoft.Logic/integrationAccounts/agreements'; CreatedTime = [datetime]::UtcNow; ChangedTime = [datetime]::UtcNow }
+                }
+
+                # Act
+                { Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath } | 
+                    Should -Not -Throw
+ 
+                # Assert
+                Assert-VerifiableMock
+                Assert-MockCalled Get-AzIntegrationAccount -Times 1
+                Assert-MockCalled Get-AzIntegrationAccountAgreement -Times 1
+                Assert-MockCalled Set-AzIntegrationAccountAgreement -Times 0
+                Assert-MockCalled New-AzIntegrationAccountAgreement -Times 1
+            }
+            It "Providing only the agreementFilePath to update an agreement is OK" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+				$agreementName = 'Dummy_Existing_Agreement'
+                $agreementResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName/agreements/$agreementName"
+				$agreementFilePath = "$PSScriptRoot\Files\IntegrationAccount\Agreements\$agreementName.json"
+
+                Mock Get-Content {
+                    return [pscustomobject] @{
+                        name = 'Agreement';
+                        properties = [pscustomobject] @{
+                            hostPartner = 'Partner1';
+                            guestPartner = 'Partner2';
+                            hostIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '12345';
+                            }
+                            guestIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '98765';
+                            }
+                            agreementType = 'AS2';
+                                content = [pscustomobject] @{
+                                    aS2 = [pscustomobject] @{}
+                            }
+                        }
+                    } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccountAgreement {
+                    return [pscustomobject]@{ Id = $agreementResourceId; Name = $agreementName; Type = 'Microsoft.Logic/integrationAccounts/agreements'; CreatedTime = [datetime]::UtcNow; ChangedTime = [datetime]::UtcNow }
+                } -Verifiable
+
+                Mock Set-AzIntegrationAccountAgreement {
+                    return [pscustomobject]@{ Id = $agreementResourceId; Name = $agreementName; Type = 'Microsoft.Logic/integrationAccounts/agreements'; CreatedTime = [datetime]::UtcNow; ChangedTime = [datetime]::UtcNow }
+                }
+
+                Mock New-AzIntegrationAccountAgreement {
+                    return $null
+                }
+
+                # Act
+                { Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementFilePath $agreementFilePath } | 
+                    Should -Not -Throw
+ 
+                # Assert
+                Assert-VerifiableMock
+                Assert-MockCalled Get-AzIntegrationAccount -Times 1
+                Assert-MockCalled Get-AzIntegrationAccountAgreement -Times 1
+                Assert-MockCalled Set-AzIntegrationAccountAgreement -Times 1
+                Assert-MockCalled New-AzIntegrationAccountAgreement -Times 0
+            }
+            It "Providing only a agreementsFolder to create agreements is OK" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+				        $agreementsFolder = "$PSScriptRoot\Files\IntegrationAccount\Agreements\"
+
+                Mock Get-ChildItem {
+                    return @(
+                        New-Item -Name "agreement1.json" -Type File -fo
+                        New-Item -Name "agreement2.json" -Type File -fo
+                    )
+                }
+                
+                Mock Get-Content {
+                    return [pscustomobject] @{
+                        name = 'Agreement';
+                        properties = [pscustomobject] @{
+                            hostPartner = 'Partner1';
+                            guestPartner = 'Partner2';
+                            hostIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '12345';
+                            }
+                            guestIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '98765';
+                            }
+                            agreementType = 'AS2';
+                                content = [pscustomobject] @{
+                                    aS2 = [pscustomobject] @{}
+                            }
+                        }
+                    } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccountAgreement {
+                    return $null
+                } -Verifiable
+
+                Mock Set-AzIntegrationAccountAgreement {
+                    return $null
+                }
+
+                Mock New-AzIntegrationAccountAgreement {
+                    return [pscustomobject]@{ Id = 'fake-resource-id'; Name = 'DummyAgreement'; Type = 'Microsoft.Logic/integrationAccounts/agreements'; CreatedTime = [datetime]::UtcNow; ChangedTime = [datetime]::UtcNow }
+                }
+
+                # Act
+                { Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementsFolder $agreementsFolder } | 
+                    Should -Not -Throw
+ 
+                # Assert
+                Assert-VerifiableMock
+                Assert-MockCalled Get-AzIntegrationAccount -Times 1
+                Assert-MockCalled Get-AzIntegrationAccountAgreement -Times 2
+                Assert-MockCalled Set-AzIntegrationAccountAgreement -Times 0
+                Assert-MockCalled New-AzIntegrationAccountAgreement -Times 2
+            }
+            It "Providing only a agreementsFolder to update agreements is OK" {
+                # Arrange
+                $subscriptionId = [guid]::NewGuid()
+                $resourceGroupName = "rg-infrastructure"
+                $integrationAccountName = "unexisting-integration-account"
+                $integrationAccountResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Logic/integrationAccounts/$integrationAccountName"
+				        $agreementsFolder = "$PSScriptRoot\Files\IntegrationAccount\Agreements\"
+
+                Mock Get-ChildItem {
+                    return @(
+                        New-Item -Name "agreement1.json" -Type File -fo
+                        New-Item -Name "agreement2.json" -Type File -fo
+                    )
+                }
+
+                Mock Get-Content {
+                    return [pscustomobject] @{
+                        name = 'Agreement';
+                        properties = [pscustomobject] @{
+                            hostPartner = 'Partner1';
+                            guestPartner = 'Partner2';
+                            hostIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '12345';
+                            }
+                            guestIdentity = [pscustomobject] @{
+                                qualifier = '1';
+                                value = '98765';
+                            }
+                            agreementType = 'AS2';
+                                content = [pscustomobject] @{
+                                    aS2 = [pscustomobject] @{}
+                            }
+                        }
+                    } | ConvertTo-Json -Depth 5;
+                } -Verifiable
+                
+                Mock Get-AzIntegrationAccount {
+                    return [pscustomobject]@{ Id = $integrationAccountResourceId; Name = $integrationAccountName; Type = 'Microsoft.Logic/integrationAccounts'; Location = 'westeurope'; Sku = 'Free' }
+                } -Verifiable
+
+                Mock Get-AzIntegrationAccountAgreement {
+                    return [pscustomobject]@{ Id = 'fake-resource-id'; Name = 'DummyAgreement'; Type = 'Microsoft.Logic/integrationAccounts/agreements'; CreatedTime = [datetime]::UtcNow; ChangedTime = [datetime]::UtcNow }
+                } -Verifiable
+
+                Mock Set-AzIntegrationAccountAgreement {
+                    return [pscustomobject]@{ Id = 'fake-resource-id'; Name = 'DummyAgreement'; Type = 'Microsoft.Logic/integrationAccounts/agreements'; CreatedTime = [datetime]::UtcNow; ChangedTime = [datetime]::UtcNow }
+                }
+
+                Mock New-AzIntegrationAccountAgreement {
+                    return $null
+                }
+
+                # Act
+                { Set-AzIntegrationAccountAgreements -ResourceGroupName $resourceGroupName -Name $integrationAccountName -AgreementsFolder $agreementsFolder } | 
+                    Should -Not -Throw
+ 
+                # Assert
+                Assert-VerifiableMock
+                Assert-MockCalled Get-AzIntegrationAccount -Times 1
+                Assert-MockCalled Get-AzIntegrationAccountAgreement -Times 2
+                Assert-MockCalled Set-AzIntegrationAccountAgreement -Times 2
+                Assert-MockCalled New-AzIntegrationAccountAgreement -Times 0
+            }
+        }
     }
 }
\ No newline at end of file