Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement of Misc/Set-BcContainerFeatureKeys.ps1 to be able to Enable Feature key for particular company. #3696

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion BC.SaasHelper.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
. (Join-Path $PSScriptRoot "Saas\Get-BcEnvironmentUsedStorage.ps1")
. (Join-Path $PSScriptRoot "Saas\Get-BcEnvironmentUpdateWindow")
. (Join-Path $PSScriptRoot "Saas\Get-BcEnvironmentInstalledExtensions.ps1")
. (Join-Path $PSScriptRoot "Saas\Get-BcEnvironmentSessions.ps1")
. (Join-Path $PSScriptRoot "Saas\Get-BcNotificationRecipients.ps1")
. (Join-Path $PSScriptRoot "Saas\Get-BcEnvironmentPublishedApps.ps1")
. (Join-Path $PSScriptRoot "Saas\Get-BcEnvironmentScheduledUpgrade.ps1")
Expand All @@ -16,10 +17,12 @@
. (Join-Path $PSScriptRoot "Saas\New-BcNotificationRecipient.ps1")
. (Join-Path $PSScriptRoot "Saas\Publish-PerTenantExtensionApps.ps1")
. (Join-Path $PSScriptRoot "Saas\Remove-BcEnvironment.ps1")
. (Join-Path $PSScriptRoot "Saas\Remove-BcEnvironmentSession.ps1")
. (Join-Path $PSScriptRoot "Saas\Rename-BcEnvironment.ps1")
. (Join-Path $PSScriptRoot "Saas\Reschedule-BcEnvironmentUpgrade.ps1")
. (Join-Path $PSScriptRoot "Saas\Restart-BcEnvironment.ps1")
. (Join-Path $PSScriptRoot "Saas\Restore-BcEnvironment.ps1")
. (Join-Path $PSScriptRoot "Saas\Set-BcEnvironmentApplicationInsightsKey.ps1")
. (Join-Path $PSScriptRoot "Saas\Set-BcEnvironmentUpdateWindow.ps1")
. (Join-Path $PSScriptRoot "Saas\Wait-BcEnvironmentReady.ps1")
. (Join-Path $PSScriptRoot "Saas\Download-BcEnvironmentInstalledExtensionToFolder.ps1")
. (Join-Path $PSScriptRoot "Saas\Download-BcEnvironmentInstalledExtensionToFolder.ps1")
5 changes: 4 additions & 1 deletion BcContainerHelper.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ FunctionsToExport = 'Add-FontsToBcContainer', 'Add-GitToAlProjectFolder',
'Get-BcEnvironmentAvailableRestorePeriods',
'Get-BcEnvironmentDatabaseExportHistory',
'Get-BcEnvironmentInstalledExtensions', 'Download-BcEnvironmentInstalledExtensionToFolder',
'Get-BcEnvironmentOperations', 'Get-BcEnvironmentPublishedApps',
'Get-BcEnvironmentOperations', 'Get-BcEnvironmentPublishedApps',
'Get-BcEnvironmentSessions',
'Get-BcEnvironments', 'Get-BcEnvironmentScheduledUpgrade',
'Get-BcEnvironmentUpdateWindow', 'Get-BcEnvironmentUsedStorage',
'Get-BcNotificationRecipients', 'Get-BcNuGetPackage',
Expand Down Expand Up @@ -154,6 +155,7 @@ FunctionsToExport = 'Add-FontsToBcContainer', 'Add-GitToAlProjectFolder',
'Remove-BcCompilerFolder', 'Remove-BcContainer',
'Remove-BcContainerSession', 'Remove-BcContainerTenant',
'Remove-BcDatabase', 'Remove-BcEnvironment',
'Remove-BcEnvironmentSession',
'Remove-CompanyInBcContainer', 'Remove-ConfigPackageInBcContainer',
'Remove-DesktopShortcut', 'Rename-BcEnvironment',
'Renew-BcAuthContext', 'Renew-LetsEncryptCertificate',
Expand All @@ -162,6 +164,7 @@ FunctionsToExport = 'Add-FontsToBcContainer', 'Add-GitToAlProjectFolder',
'Resolve-DependenciesFromAzureFeed', 'Restart-BcContainer',
'Restart-BcContainerServiceTier', 'Restore-BcDatabaseFromArtifacts',
'Restore-BcEnvironment', 'Restore-DatabasesInBcContainer',
'Restart-BcEnvironment',
'Run-AlCops', 'Run-AlPipeline', 'Run-AlValidation',
'Run-BCPTTestsInBcContainer', 'Run-ConnectionTestToBcContainer',
'Run-TestsInBcContainer', 'Set-BcContainerFeatureKeys',
Expand Down
52 changes: 40 additions & 12 deletions Misc/Set-BcContainerFeatureKeys.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<#
<#
.Synopsis
Set Feature Keys in container
.Description
Expand All @@ -9,8 +9,11 @@
Tenant in which you want to set feature keys
.Parameter featureKeys
Hashtable of featureKeys you want to set
.Parameter EnableInCompany
Enables/disables features for given company name. No data update is initiated.
.Example
Set-BcContainerFeatureKeys -containerName test2 -featureKeys @{"EmailHandlingImprovements" = "None"}
Set-BcContainerFeatureKeys -containerName test2 -featureKeys @{"EmailHandlingImprovements" = "None"} -EnableInCompany 'CRONUS International Ltd.'
#>
function Set-BcContainerFeatureKeys {
Param (
Expand All @@ -19,14 +22,16 @@ function Set-BcContainerFeatureKeys {
[Parameter(Mandatory=$false)]
[string] $tenant = "*",
[Parameter(Mandatory=$true)]
[hashtable] $featureKeys
[hashtable] $featureKeys,
[Parameter(Mandatory=$false)]
[string] $EnableInCompany
)

$telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @("featureKeys")
try {

if ($featureKeys.Keys.Count -ne 0) {
Invoke-ScriptInBCContainer -containerName $containerName -ScriptBlock { Param([string] $tenant, [hashtable] $featureKeys)
Invoke-ScriptInBCContainer -containerName $containerName -ScriptBlock { Param([string] $tenant, [hashtable] $featureKeys, $EnableInCompany)
$customConfigFile = Join-Path (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName "CustomSettings.config"
[xml]$customConfig = [System.IO.File]::ReadAllText($customConfigFile)
$databaseServer = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value
Expand Down Expand Up @@ -55,6 +60,13 @@ try {
$databases | % {
$databaseName = $_
Write-Host "Setting feature keys on database: $databaseName"
# Just information about 'mode' of Feature Key update
if ([String]::IsNullOrEmpty($EnableInCompany)) {
Write-Host "Setting feature keys globally, but not for any company" -ForegroundColor Yellow
}
else {
Write-Host "Setting feature keys globally and for company "$EnableInCompany -ForegroundColor Yellow
}
$featureKeys.Keys | % {
$featureKey = $_
$enabledStr = $featureKeys[$featureKey]
Expand All @@ -68,23 +80,39 @@ try {
$enabled = -1
Write-Host "WARNING: Unknown value ($enabledStr) for feature key $featureKey"
}
if ($enabled -ne -1) {

# Test if feature which has to be updated is available in table "Feature Data Update Status$63ca2fa4-4f03-4f2b-a480-172fef340d3f"
$FeatureExistsInDestination = Invoke-Sqlcmd -Database $databaseName -Query $("SELECT COUNT(*) FROM [dbo].[Feature Data Update Status"+'$'+"63ca2fa4-4f03-4f2b-a480-172fef340d3f] where [Feature Key] = '$featureKey'")

if(($FeatureExistsInDestination[0].ToString()) -eq "0") {
Write-host "Feature $featureKey doesn't exist in database - Failure"
}

# Feature key is updated just in case that status is correct and respective feature is available in table "Feature Data Update Status$63ca2fa4-4f03-4f2b-a480-172fef340d3f"
if (($enabled -ne -1) -and ($FeatureExistsInDestination[0].ToString() -ne "0")) {
try {
#Create new record in table of feature setup table [Tenant Feature Key] in case it is missing
#Create new record in table "Tenant Feature Key" in case it is missing
$SQLRecord = Invoke-Sqlcmd -Database $databaseName -Query "SELECT * FROM [dbo].[Tenant Feature Key] where ID = '$featureKey'"
if ([String]::IsNullOrEmpty($SQLRecord))
{
Write-host "Creating record for feature ID '$featureKey'"
if ([String]::IsNullOrEmpty($SQLRecord)) {
Write-host "Creating record for feature $featureKey"
$SQLcolumns = "ID, Enabled"
$SQLvalues = "'$featureKey',0"
Invoke-Sqlcmd -Database $databaseName -Query "INSERT INTO [CRONUS].[dbo].[Tenant Feature Key] ($SQLcolumns) VALUES ($SQLvalues)" -Verbose
Invoke-Sqlcmd -Database $databaseName -Query "INSERT INTO [dbo].[Tenant Feature Key] ($SQLcolumns) VALUES ($SQLvalues)" -Verbose
}
Write-Host -NoNewline "Setting feature key $featureKey to $enabledStr - "
$result = Invoke-Sqlcmd -Database $databaseName -Query "UPDATE [dbo].[Tenant Feature Key] set Enabled = $enabled where ID = '$featureKey';Select @@ROWCOUNT"
if ($result[0] -eq "1") {
Write-Host " Success"
# Update record in table "Feature Data Update Status$63ca2fa4-4f03-4f2b-a480-172fef340d3f" if it is requested for particular company
if (![String]::IsNullOrEmpty($EnableInCompany)) {
Write-Host -NoNewline "Setting feature key $featureKey to $enabledStr for Company $EnableInCompany - "
$result = Invoke-Sqlcmd -Database $databaseName -Query $("UPDATE [dbo].[Feature Data Update Status"+'$'+"63ca2fa4-4f03-4f2b-a480-172fef340d3f] set [Feature Status] = $enabled where [Feature Key] = '$featureKey' AND [Company Name] = '$EnableInCompany';Select @@ROWCOUNT")
if ($result[0] -eq "1") {
Write-Host " Success"
}
}
}
else {
if ($result[0] -ne "1") {
throw
}
}
Expand All @@ -95,7 +123,7 @@ try {
}
}
}
} -argumentList $tenant, $featureKeys
} -argumentList $tenant, $featureKeys, $EnableInCompany
}
}
catch {
Expand Down
55 changes: 55 additions & 0 deletions Saas/Get-BcEnvironmentSessions.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<#
.Synopsis
Function for retrieving a list of current sessions for given environment from an online Business Central tenant
.Description
Function for retrieving a list of current sessions for given environment from an online Business Central tenant
Wrapper for https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/administration/administration-center-api_session_management#get-active-sessions
.Parameter bcAuthContext
Authorization Context created by New-BcAuthContext.
.Parameter applicationFamily
Application Family in which the environment is located. Default is BusinessCentral.
.Parameter environment
Name of the environment
.Parameter apiVersion
API version. Default is v2.21.
.Example
$authContext = New-BcAuthContext -includeDeviceLogin
Get-BcEnvironmentSessions -bcAuthContext $authContext -environment "MySandbox"
#>
function Get-BcEnvironmentSessions {
Param(
[Parameter(Mandatory = $true)]
[Hashtable] $bcAuthContext,
[string] $applicationFamily = "BusinessCentral",
[Parameter(Mandatory = $true)]
[string] $environment = "",
[string] $apiversion = "v2.21"
)

$telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @()
try {
$bcAuthContext, $headers, $endPointURL = Create-SaasUrl -bcAuthContext $bcAuthContext -endPoint "sessions" -environment $environment -applicationFamily $applicationFamily -apiVersion $apiVersion
try {
$Result = (Invoke-RestMethod -Method Get -UseBasicParsing -Uri $endPointURL -Headers $headers)
if ($Result.PSObject.Properties.Name -eq 'Value') {
$Result.Value
}
else {
$Result
}
}
catch {
Write-Host $_
throw (GetExtendedErrorMessage $_)
}
}
catch {
TrackException -telemetryScope $telemetryScope -errorRecord $_
throw
}
finally {
TrackTrace -telemetryScope $telemetryScope
}
}

Export-ModuleMember -Function Get-BcEnvironmentSessions
61 changes: 61 additions & 0 deletions Saas/Remove-BcEnvironmentSession.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<#
.Synopsis
Function for stopping and deletion of session from environment (from an online Business Central tenant)
.Description
Function for stop and deletion of session from environment (from an online Business Central tenant)
Wrapper for https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/administration/administration-center-api_session_management#stop-and-delete-a-session
.Parameter SessionID
Session ID of session to be stopped and deleted.
.Parameter bcAuthContext
Authorization Context created by New-BcAuthContext.
.Parameter applicationFamily
Application Family in which the environment is located. Default is BusinessCentral.
.Parameter environment
Name of the environment
.Parameter apiVersion
API version. Default is v2.21.
.Example
$authContext = New-BcAuthContext -includeDeviceLogin
Remove-BcEnvironmentSession -bcAuthContext $authContext -environment "MySandbox"
#>
function Remove-BcEnvironmentSession {
Param(
[Parameter(Mandatory = $true)]
[Hashtable] $bcAuthContext,
[Parameter(Mandatory = $true)]
[string] $sessionID,
[string] $applicationFamily = "BusinessCentral",
[Parameter(Mandatory = $true)]
[string] $environment = "",
[string] $apiversion = "v2.21"
)

$telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @()
try {
$bcAuthContext, $headers, $endPointURL = Create-SaasUrl -bcAuthContext $bcAuthContext -endPoint "sessions/$sessionID" -environment $environment -applicationFamily $applicationFamily -apiVersion $apiVersion

Write-Host "Submitting session deletion request for session ID $sessionID in $environment"

try {
$Result = (Invoke-RestMethod -Method Delete -UseBasicParsing -Uri $endPointURL -Headers $headers)

}
catch {
Write-Host $_
throw (GetExtendedErrorMessage $_)
}
Write-Host "Session deletion request submitted"

}


catch {
TrackException -telemetryScope $telemetryScope -errorRecord $_
throw
}
finally {
TrackTrace -telemetryScope $telemetryScope
}
}

Export-ModuleMember -Function Remove-BcEnvironmentSession
81 changes: 81 additions & 0 deletions Saas/Restart-BcEnvironment.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<#
.Synopsis
Function for restarting a Business Central online environment
.Description
Function for restarting a Business Central online environment
.Parameter bcAuthContext
Authorization Context created by New-BcAuthContext.
.Parameter applicationFamily
Application Family in which the environment is located. Default is BusinessCentral.
.Parameter environment
Name of the environment for restarting
.Parameter apiVersion
API version. Default is v2.21.
.Parameter doNotWait
Include this switch if you don't want to wait for completion of the environment
.Example
$authContext = New-BcAuthContext -includeDeviceLogin
Restart-BcEnvironment -bcAuthContext $authContext -environment 'MySandbox'
#>
function Restart-BcEnvironment {
Param(
[Parameter(Mandatory = $true)]
[Hashtable] $bcAuthContext,
[Parameter(Mandatory = $true)]
[string] $environment,
[Parameter(Mandatory = $false)]
[string] $applicationFamily = "BusinessCentral",
[Parameter(Mandatory = $false)]
[string] $apiversion = "v2.21",
[Parameter(Mandatory = $false)]
[switch] $doNotWait
)

$telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @()
try {
$bcAuthContext = Renew-BcAuthContext -bcAuthContext $bcAuthContext
Wait-BcEnvironmentsReady -environments @($environment) -bcAuthContext $bcAuthContext -apiVersion $apiVersion -applicationFamily $applicationFamily

$bcEnvironments = Get-BcEnvironments -bcAuthContext $bcAuthContext -applicationFamily $applicationFamily -apiVersion $apiVersion
$bcEnvironment = $bcEnvironments | Where-Object { $_.name -eq $environment }
if (!($bcEnvironment)) {
throw "No environment named $environment exists"
}


$bcAuthContext, $headers, $endPointURL = Create-SaasUrl -bcAuthContext $bcAuthContext -endPoint "restart" -environment $environment -applicationFamily $applicationFamily -apiVersion $apiVersion

Write-Host "Submitting environment restart request for $environment"

try {
$environmentResult = (Invoke-RestMethod -Method POST -Uri $endPointURL -Headers $headers -ContentType 'application/json')
}
catch {
throw (GetExtendedErrorMessage $_)
}
Write-Host "Restart environment request submitted"

if (!$doNotWait) {
Write-Host -NoNewline "Restarting."
do {
Start-Sleep -Seconds 2
Write-Host -NoNewline "."
$bcAuthContext = Renew-BcAuthContext -bcAuthContext $bcAuthContext
$Operation = (Get-BcOperations -bcAuthContext $bcAuthContext -apiVersion $apiVersion -applicationFamily $applicationFamily | Where-Object { ($_.productFamily -eq $applicationFamily) -and ($_.type -eq $environmentResult.type) -and ($_.id -eq $environmentResult.id) })
} while ($Operation.status -in "queued", "scheduled", "running")
Write-Host $Operation.status
if ($Operation.status -eq "failed") {
throw "Could not restart environment with error: $($Operation.errorMessage)"
}
}
}
catch {
TrackException -telemetryScope $telemetryScope -errorRecord $_
throw
}
finally {
TrackTrace -telemetryScope $telemetryScope
}
}

Export-ModuleMember -Function Restart-BcEnvironment