$isDomainPrompt              = "Are the devices for migration in the domain? Y/N"
$kscCredentialsPrompt        = "Enter KSC Installation Administrator credentials:"
$kscUserNamePrompt           = "Username"
$kscUserPasswordPrompt       = "Password"
$kesCloudPackagePathPrompt   = "Specify the path to KES Cloud installation package"
$kesCloudInstallCredsPrompt  = "Enter credentials for local admin on endpoints:"
$kesCloudInstallAccPrompt    = "Username"
$kesCloudInstallPwdPrompt    = "Password"

$forceRestartPrompt          = "The computers need to be restarted for successful migration."
$forceRestartPrompt2         = "Force Restart? Y/N"
$restartAfterPrompt          = "Restart after (enter the number of minutes)"

$installationPackageName     = "KSC to KES Cloud migration - Installation package"
$queryName                   = "KSC to KES Cloud migration - Devices to migrate"
$uninstallTaskName           = "KSC to KES Cloud migration - Uninstall"
$installTaskName             = "KSC to KES Cloud migration - Install KES Cloud"

$doneResult                  = "Done"
$connectingToKscAction       = "Connecting to KSC server..."
$creatingTempFolderAction    = "Creating temporary folder..."
$preparationPackageAction    = "Preparation of an installation package..."
$creatingPackageAction       = "Creating the `"$installationPackageName`" installation package..."
$creatingQyeryAction         = "Creating the `"$queryName`" device selection..."
$creatingUninstallTaskAction = "Creating the `"$uninstallTaskName`" task..."
$creatingInstallTaskAction   = "Creating the `"$installTaskName`" task..."
$startingUninstallTaskAction = "Starting the `"$uninstallTaskName`" task..."
$deletingActionFormat        = "Deleting `"{0}`"..."

$noDomainStartTaskPrompt     = "Do you want to start migration now?
Y – You’ll need to:
1) Go to KSC.
2) Make sure hosts rebooted successfully.
3) Within the installation task specify administrator accounts for endpoints for package installation.
4) Run `"$installTaskName`" task.
5) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them.
N – You'll need to:
1) Go to KSC.
2) Run `"$uninstallTaskName`" task.
3) Make sure hosts rebooted successfully after that.
4) Within the installation task specify administrator accounts for endpoints for package installation.
5) Run `"$installTaskName`" task.
6) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them."

$domainStartTaskPrompt       = "Do you want to start migration now?
Y – You’ll need to:
1) Go to KSC and run `"$installTaskName`" task manually after the computers rebooted.
2) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them.
N – You'll need to go to KSC and run both tasks manually:
1) Run `"$uninstallTaskName`" task.
2) Make sure hosts rebooted successfully after that.
3) Run `"$installTaskName`" task.
4) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them."

$startTaskPromptYesNo        = "Y/N"

$noDomainRunManuallyMessage  = "The two tasks for migration were successfully created.
1) Go to KSC and run `"$uninstallTaskName`" task.
2) Make sure hosts rebooted successfully after that.
3) Within the installation task specify administrator accounts for endpoints for package installation.
4) Run `"$installTaskName`" task.
5) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them."

$domainRunManuallyMessage    = "The two tasks for migration were successfully created.
1) Go to KSC and run `"$uninstallTaskName`" task.
2) Make sure hosts rebooted successfully after that.
3) Run `"$installTaskName`" task.
4) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them."

$noDomainFinalMessage        = "1) Go to KSC.
2) Make sure hosts rebooted successfully.
3) Within the installation task specify administrator accounts for endpoints for package installation.
4) Run `"$installTaskName`" task.
5) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them."

$domainFinalMessage          = "1) Go to KSC and run `"$installTaskName`" task manually after the computers rebooted.
2) After Install task is completed successfully your Windows devices will be connected to KES Cloud. `"Default`" security profile (recommended by Kaspersky) will be automatically applied to each of them."

$scriptCompletedMessage      = "Script completed. Press 'Enter' to exit"

function Write-Stage
{
	Param(
	[string]$stage
	)

    Write-Host "$stage " -NoNewline
}

function Write-Done
{
    Write-Host $doneResult -ForegroundColor Green
}

function Read-PromptReply
{
	Param(
    [string]$promptMessage,
    [string]$replyRegEx
	)

    do
    {
        $reply = Read-Host $promptMessage
    }
    while ($reply -notmatch $replyRegEx)

    return $reply
}

function Convert-JsonValueToKlakaut
{
	Param(
	[object]$value
	)

    if ($value -is [PSCustomObject])
    {
        $type = $value.type
        if ($type -eq "datetime")
        {
            $dateTimeString = $value.value
            if ($dateTimeString -eq "")
            {
                $dateTimeString = "1969-12-31T23:59:59Z"
            }
            $dateTimeValue = [datetime]::parse($dateTimeString).ToUniversalTime()
            return $dateTimeValue
        }
        elseif ($type -eq "params")
        {
            $oParamsValue = Convert-JsonToKlakaut $value.value
            return ,$oParamsValue
        }
        elseif ($type -eq "binary")
        {
            [byte[]]$byteArrayValue = @()
            return ,$byteArrayValue
        }
    }
    elseif ($value -is [array])
    {
        $oCollectionValue = New-Object -ComObject klakaut.KlAkCollection
        $oCollectionValue.SetSize($value.Length)
        for ($index = 0; $index -lt $value.Length; $index++)
        {
            $collectionItem = Convert-JsonValueToKlakaut $value[$index]
            $oCollectionValue.SetAt($index, $collectionItem)
        }
        return ,$oCollectionValue
    }
    
    return $value
}

function Convert-JsonToKlakaut
{
	Param(
	[PSCustomObject]$src
	)

    $oResultParams = New-Object -ComObject klakaut.KlAkParams

    foreach ($property in $src.psobject.properties.name)
    {
        $value = $src.$property
        $klakautValue = Convert-JsonValueToKlakaut $value
        $oResultParams.Add($property, $klakautValue)
    }

    return ,$oResultParams
}

function ConvertTo-PlainText
{
	Param(
	[security.securestring]$secure
	)

    $marshal = [Runtime.InteropServices.Marshal]
    return $marshal::PtrToStringAuto($marshal::SecureStringToBSTR($secure))
}

function KSC-LogIn
{
	Param(
	[string]$user,
	[string]$password
	)

	$oSrvConnectionProps = New-Object -ComObject klakaut.KlAkParams

	$oSrvConnectionProps.Add("UseSSL",   $true);
	$oSrvConnectionProps.Add("User",     $user);
	$oSrvConnectionProps.Add("Password", $password);
	$oSrvConnectionProps.Add("Address",  "localhost:13291");

	$oAdmServer = New-Object -ComObject klakaut.KlAkProxy
	$oAdmServer.Connect($oSrvConnectionProps);

	return $oAdmServer;
}

function Set-TaskDisplayName
{
	Param(
    [object]$task,
	[string]$displayName
	)

    $infoParams = $task.Item("TASK_INFO_PARAMS")
    $infoParams.Add("DisplayName", $displayName)
}

function Set-TaskQuery
{
	Param(
	[object]$task,
    [int]$queryId,
    [string]$queryName,
    [string]$queyFilter
	)

    $infoParams = $task.Item("TASK_INFO_PARAMS")
    $infoParams.Add(".HstQueryId", $queryId)
    $infoParams.Add("KLTSK_HST_QUERY_FILTER", $queyFilter)
    $infoParams.Add("KLTSK_HST_QUERY_NESTLING_LEVEL", 0)
    $infoParams.Add(".KLTSK_MASTER_QUERY_NAME", $queryName)
}

function Set-TaskAccount
{
	Param(
	[object]$task,
	[object]$oTasks,
    [string]$accountName,
    [string]$accountPassword
	)

    $protectedPassword = $oTasks.ProtectPassword($kesCloudInstallationPassword)
    
    $accountParams = New-Object -ComObject klakaut.KlAkParams
    $accountParams.Add("klprts-TaskAccountAuthType", 1)
    $accountParams.Add("klprts-TaskAccountPassword", $protectedPassword)
    $accountParams.Add("klprts-TaskAccountUser", $accountName)
    
    $accountCollection = New-Object -ComObject klakaut.KlAkCollection
    $accountCollection.SetSize(1)
    $accountCollection.SetAt(0, $accountParams)

    $additionalParams = $task.Item("TASK_ADDITIONAL_PARAMS")
    $additionalParams.Add("klprts-TaskAccounts", $accountCollection)
}

function Set-TaskInstallationPackage
{
	Param(
	[object]$task,
    [int]$packageId
	)

    $additionalParams = $task.Item("TASK_ADDITIONAL_PARAMS")
    $packageCollection = New-Object -ComObject klakaut.KlAkCollection
    $packageCollection.SetSize(1)
    $packageCollection.SetAt(0, $packageId)
    $additionalParams.Add("KLTSK_RI_PACKAGES_IDS", $packageCollection)
}

function Set-TaskRestartAfter
{
	Param(
	[object]$task,
    [int]$restartAfter
	)

    $additionalParams = $task.Item("TASK_ADDITIONAL_PARAMS")
    $additionalParams.Add("KLTSK_RU_REBOOT_FORCE_REBOOT_PERIOD", $restartAfter)
}

function KSC-PreparePackage
{
	Param(
	[string]$tempFolderPath,
    [string]$packagePath
	)

    $packageFileName = Split-Path $packagePath -leaf
    $tempFolderExec = Join-Path $tempFolderPath "exec"
    $null = New-Item -ItemType Directory -Path $tempFolderExec

    Copy-Item -Path $packagePath -Destination $tempFolderExec

    $kpdFile = Join-Path $tempFolderPath "executable_package.kpd"
    $null = New-Item -Path $kpdFile -ItemType File
    $kpdFileContent = "[Setup]
Executable=exec\$packageFileName
Params=-s
[Product]
LocalizedName=$packageFileName
Name=executable_package
[Version]
VerMajor=1
VerMinor=0
VerBuild=0
VerPatch=0
[SetupProcessResult]
Wait=1
[SetupProcessResult_SuccessCodes]
0=
1=
[SetupProcessResult_WarningCodes]
3=
[SetupProcessResult_NeedReboot]
1=
3=
5="
    Set-Content $kpdFile $kpdFileContent

    $acl = Get-Acl $tempFolderPath
    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("KLAdmins", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
    $acl.SetAccessRule($accessRule)
    $acl | Set-Acl $tempFolderPath
}

function KSC-CreateQuery
{
	Param(
	[object]$oQueries,
    [string]$kscHostId,
    [string]$queryName
	)

    $queryString = '(&(KLHST_WKS_PTYPE=2)(KLHST_WKS_HOSTNAME<>"' + $kscHostId + '")(KLHST_WKS_FROM_UNASSIGNED=0))'
    $queryData = New-Object -ComObject klakaut.KlAkParams
    $queryData.Add("Name", $queryName)
    $queryData.Add("QueryVer", 2)
    $queryData.Add("Query", $queryString)

    $osPageSettings = New-Object -ComObject klakaut.KlAkParams
    $osPageSettings.Add("Query", $queryString)
    $queryPart = New-Object -ComObject klakaut.KlAkParams
    $queryPart.Add("Name", $queryName)
    $queryPart.Add("OsPageSettings", $osPageSettings)
    $queryPartsCollection = New-Object -ComObject klakaut.KlAkCollection
    $queryPartsCollection.SetSize(1)
    $queryPartsCollection.SetAt(0, $queryPart)
    $queryData.Add("ORedArray", $queryPartsCollection)

    return $oQueries.AddQuery(1, $queryData)
}

function KSC-Cleanup
{
	Param(
	[object]$oQueries,
    [object]$oPackages,
    [object]$oTasks
	)

    foreach ($task in $oTasks.EnumTasks(-1))
    {
        $taskDisplayName = $task.Item("DisplayName")
        if (($taskDisplayName -eq $installTaskName) -or ($taskDisplayName -eq $uninstallTaskName))
        {
            $stage = [string]::Format($deletingActionFormat, $taskDisplayName)
            Write-Stage -stage $stage
            $taskId = $task.Item("TASK_UNIQUE_ID")
            $oTasks.DeleteTask($taskId)
            Write-Done
        }
    }

    foreach ($query in $oQueries.GetQueries(1))
    {
        $queryData = $query.Item("KLQRS_QUERY_DATA")
        $name = $queryData.Item("Name")
        if ($name -eq $queryName)
        {
            $stage = [string]::Format($deletingActionFormat, $name)
            Write-Stage -stage $stage
            $queryId = $query.Item("KLQRS_QUERY_ID")
            $oQueries.DeleteQuery($queryId)
            Write-Done
        }
    }

    foreach ($package in $oPackages.GetPackages())
    {
        $packageName = $package.Item("KLPKG_DN")
        if ($packageName -eq $installationPackageName)
        {
            $stage = [string]::Format($deletingActionFormat, $packageName)
            Write-Stage -stage $stage
            $packageId = $package.Item("KLPKG_ID")
            $oPackages.DeletePackage($packageId)
            Write-Done
        }
    }
}

$uninstallTaskTemplate = '
{
    "EVENT_TYPE": "PRTS_EVENT_NONE",
    "FILTER_EVENTS_COMPONENT_NAME": "",
    "FILTER_EVENTS_INSTANCE_ID": "",
    "FILTER_EVENTS_PRODUCT_NAME": "",
    "FILTER_EVENTS_VERSION": "",
    "TASKID_COMPONENT_NAME": "87",
    "TASKID_INSTANCE_ID": "",
    "TASKID_PRODUCT_NAME": "1093",
    "TASKID_VERSION": "1.0.0.0",
    "TASKSCH_FIRST_EXECUTION_TIME": { "type": "datetime", "value": "1970-01-01T00:00:00Z" },
    "TASKSCH_FIRST_EXECUTION_TIME_SEC": 0,
    "TASKSCH_LIFETIME": { "type": "datetime", "value": "" },
    "TASKSCH_MS_PERIOD": 0,
    "TASKSCH_RUN_MISSED_FLAG": true,
    "TASKSCH_TYPE": 0,
    "TASK_ADDITIONAL_PARAMS":
    {
      "type": "params",
      "value": {
        "DeinstallationPassword": { "type": "binary", "value": "" },
        "KLTSK_RI_CHECK_OS": false,
        "KLTSK_RI_MAX_DOWNLOADS": 5,
        "KLTSK_RI_USE_NAGENT": true,
        "KLTSK_RI_USE_SHARE": false,
        "KLTSK_RI_USE_SHARE_SRV": false,
        "KLTSK_RI_USE_SHARE_UA": false,
        "KLTSK_RU_FORCE_APPS_CLOSED": false,
        "KLTSK_RU_REBOOT_ASK_FOR_REBOOT": true,
        "KLTSK_RU_REBOOT_ASK_FOR_REBOOT_PERIOD": 5,
        "KLTSK_RU_REBOOT_FORCE_REBOOT_PERIOD": 30,
        "KLTSK_RU_REBOOT_IMMEDIATELY": false,
        "KLTSK_RU_REBOOT_MESSAGE":
          "Uninstallation has completed. Your operating system must be restarted to finish uninstallation.",
        "MaxTryCount": 3,
        "ProductDisplayName": "All managed applications",
        "ProductName": "AllControlledProducts",
        "ProductVersion": "AllControlledProducts",
        "UninstallType": 0,
        "UseGPO": false,
        "klprts-TaskAccountUser": "",
        "klprts-TaskAccounts": [],
        "klprts-TaskMaxRunningTime": 0
      }
    },
    "TASK_CLASS_ID": 0,
    "TASK_DEL_AFTER_RUN_FLAG": false,
    "TASK_INFO_PARAMS": {
      "type": "params",
      "value": {
        "HostList": [],
        "KLPRSS_EVPNotifications":
        {
          "type": "params",
          "value": {
            "ERR":
            [
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              }
            ],
            "INF": [
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_BODY_FILTER": { "type": "params", "value": { "KLPRCI_newState": 2 } },
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              },
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLEVP_GroupTaskSyncState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              },
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_BODY_FILTER": { "type": "params", "value": { "KLPRCI_newState": 4 } },
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              },
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_BODY_FILTER": { "type": "params", "value": { "KLPRCI_newState": 1 } },
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              }
            ],
            "WRN": [
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              }
            ]
          }
        },
        "KLSRV_PRTS_TASK_ENABLED_FLAG": true,
        "KLTSK_ALLOW_AUTO_RANDOMIZATION": true,
        "PRTS_TASK_GROUPID": -1,
        "PRTS_TASK_TARGET_COMPUTERS_TYPE": 2,
        "klprts-DontApplyToSlaveServers": true,
        "klprts-TaskMaxRunningTime": 0,
        "klprts-TaskScheduleSubtype": 256,
        "klprts-TaskScheduleSubtypeEx": 0
      }
    },
    "TASK_LAST_EXEC_TIME": { "type": "datetime", "value": "1970-01-01T00:00:00Z" },
    "TASK_LAST_EXEC_TIME_SEC": 0,
    "TASK_MAX_EXEC_TIME": 0,
    "TASK_NAME": "Remote Deinstallation",
    "TASK_PREP_START": 0,
    "TASK_PRIORITY": 1,
    "TASK_START_DELTA": 0
}'

$installTaskTemplate = '
{
    "EVENT_TYPE": "PRTS_EVENT_NONE",
    "FILTER_EVENTS_COMPONENT_NAME": "",
    "FILTER_EVENTS_INSTANCE_ID": "",
    "FILTER_EVENTS_PRODUCT_NAME": "",
    "FILTER_EVENTS_VERSION": "",
    "TASKID_COMPONENT_NAME": "87",
    "TASKID_INSTANCE_ID": "",
    "TASKID_PRODUCT_NAME": "1093",
    "TASKID_VERSION": "1.0.0.0",
    "TASKSCH_FIRST_EXECUTION_TIME": { "type": "datetime", "value": "1970-01-01T00:00:00Z" },
    "TASKSCH_FIRST_EXECUTION_TIME_SEC": 0,
    "TASKSCH_LIFETIME": { "type": "datetime", "value": "" },
    "TASKSCH_MS_PERIOD": 0,
    "TASKSCH_RUN_MISSED_FLAG": true,
    "TASKSCH_TYPE": 0,
    "TASK_ADDITIONAL_PARAMS":
    {
      "type": "params",
      "value": {
        "KLNAG_TASK_REMOTE_INSTALL_ACCOUNT": "",
        "KLNAG_TASK_REMOTE_INSTALL_ACCOUNT_PSWD": { "type": "binary", "value": "" },
        "KLTSK_RI_CHECK_OS": true,
        "KLTSK_RI_MAX_DOWNLOADS": 5,
        "KLTSK_RI_MGD_BY_OTHER_SERVER": 0,
        "KLTSK_RI_ROOT": { "type": "binary", "value": "" },
        "KLTSK_RI_SKIP_PRESENT_PRODS": true,
        "KLTSK_RI_TMP_FOLDER": "",
        "KLTSK_RI_USE_NAGENT": false,
        "KLTSK_RI_USE_SHARE": true,
        "KLTSK_RI_USE_SHARE_SRV": true,
        "KLTSK_RI_USE_SHARE_UA": false,
        "MaxTryCount": 3,
        "UseGPO": false,
        "klprts-TaskAccountUser": "",
        "klprts-TaskAccounts": [],
        "klprts-TaskMaxRunningTime": 7200000
      }
    },
    "TASK_CLASS_ID": 0,
    "TASK_DEL_AFTER_RUN_FLAG": false,
    "TASK_INFO_PARAMS": {
      "type": "params",
      "value": {
        "HostList": [],
        "KLPRSS_EVPNotifications":
        {
          "type": "params",
          "value": {
            "ERR":
            [
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              }
            ],
            "INF": [
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_BODY_FILTER": { "type": "params", "value": { "KLPRCI_newState": 2 } },
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              },
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLEVP_GroupTaskSyncState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              },
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_BODY_FILTER": { "type": "params", "value": { "KLPRCI_newState": 4 } },
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              },
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_BODY_FILTER": { "type": "params", "value": { "KLPRCI_newState": 1 } },
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              }
            ],
            "WRN": [
              {
                "type": "params",
                "value": {
                  "KLEVP_ND_DAYS_TO_STORE_EVENT": 7,
                  "KLEVP_ND_EVETN_TYPE": "KLPRCI_TaskState",
                  "KLEVP_ND_STORE_AT_CLIENT_LOG": false,
                  "KLEVP_ND_STORE_AT_CLIENT_PRES": false,
                  "KLEVP_ND_STORE_AT_SERVER_LOG": false
                }
              }
            ]
          }
        },
        "KLSRV_PRTS_TASK_ENABLED_FLAG": true,
        "KLTSK_ALLOW_AUTO_RANDOMIZATION": true,
        "PRTS_TASK_GROUPID": -1,
        "PRTS_TASK_TARGET_COMPUTERS_TYPE": 2,
        "klprts-DontApplyToSlaveServers": true,
        "klprts-TaskMaxRunningTime": 7200000,
        "klprts-TaskScheduleSubtype": 256,
        "klprts-TaskScheduleSubtypeEx": 0
      }
    },
    "TASK_LAST_EXEC_TIME": { "type": "datetime", "value": "1970-01-01T00:00:00Z" },
    "TASK_LAST_EXEC_TIME_SEC": 0,
    "TASK_MAX_EXEC_TIME": 0,
    "TASK_NAME": "Remote Installation",
    "TASK_PREP_START": 0,
    "TASK_PRIORITY": 1,
    "TASK_START_DELTA": 0
}'

$ErrorActionPreference = "Stop"

$isDomain = (Read-PromptReply -promptMessage $isDomainPrompt -replyRegEx "[yYnN]") -match "[yY]"
Write-Host

Write-Host $kscCredentialsPrompt
$kscUserName = Read-Host $kscUserNamePrompt
$kscUserName = $kscUserName.Trim()
$kscUserPasswordSecure = Read-Host $kscUserPasswordPrompt -AsSecureString
$kscUserPassword = ConvertTo-PlainText $kscUserPasswordSecure
Write-Host

$kesCloudPackagePath = Read-Host $kesCloudPackagePathPrompt
$kesCloudPackagePath = $kesCloudPackagePath.Trim()
$kesCloudPackagePath = $kesCloudPackagePath.Trim('"', "'")
Write-Host

if ($isDomain)
{
    Write-Host $kesCloudInstallCredsPrompt
    $kesCloudInstallationAccount = Read-Host $kesCloudInstallAccPrompt
    $kesCloudInstallationAccount = $kesCloudInstallationAccount.Trim()
    if ($kesCloudInstallationAccount)
    {
        $kesCloudInstallationPasswordSecure = Read-Host $kesCloudInstallPwdPrompt -AsSecureString
        $kesCloudInstallationPassword = ConvertTo-PlainText $kesCloudInstallationPasswordSecure
    }
    Write-Host
}

Write-Host $forceRestartPrompt
$reply = Read-PromptReply -promptMessage $forceRestartPrompt2 -replyRegEx "[yYnN]"
if ($reply -match "[yY]")
{
    [int]$restartAfterMinutesIfRequired = Read-PromptReply -promptMessage $restartAfterPrompt -replyRegEx "^[1-9]\d*$"
}
else
{
    $restartAfterMinutesIfRequired = 0
}
Write-Host

try
{
    Write-Stage -stage $connectingToKscAction
    $kscConnection = KSC-LogIn -user $kscUserName -password $kscUserPassword
    $oPackages = New-Object -ComObject klakaut.KlAkPackages5
    $oPackages.AdmServer = $kscConnection
    $oTasks = New-Object -ComObject klakaut.KlAkTasks2
    $oTasks.AdmServer = $kscConnection
    $oQueries = New-Object -ComObject klakaut.KlAkQueriesStorage
    $oQueries.AdmServer = $kscConnection
    Write-Done

    KSC-Cleanup -oPackages $oPackages -oQueries $oQueries -oTasks $oTasks

    Write-Stage -stage $creatingTempFolderAction
    [string]$tempFolderName = [System.Guid]::NewGuid()
    $tempFolder = Join-Path $env:temp $tempFolderName
    $null = New-Item -ItemType Directory -Path $tempFolder
    Write-Done

    try
    {
        Write-Stage -stage $preparationPackageAction
        KSC-PreparePackage -tempFolderPath $tempFolder -packagePath $kesCloudPackagePath
        Write-Done

        Write-Stage -stage $creatingPackageAction
        $packageId = $oPackages.AddPackage($tempFolder, $installationPackageName)
        Write-Done
    }
    finally
    {
        Remove-Item $tempFolder -Recurse
    }

    Write-Stage -stage $creatingQyeryAction
    $kscHostId = $kscConnection.GetProp("KLADMSRV_SERVER_HOSTNAME")
    $queryId = KSC-CreateQuery -oQueries $oQueries -kscHostId $kscHostId -queryName $queryName
    Write-Done

    Write-Stage -stage $creatingUninstallTaskAction
    $uninstallTaskJson = ConvertFrom-Json $uninstallTaskTemplate
    $uninstallTask = Convert-JsonToKlakaut $uninstallTaskJson
    Set-TaskDisplayName -task $uninstallTask -displayName $uninstallTaskName
    Set-TaskQuery -task $uninstallTask -queryId $queryId -queryName $queryName -queyFilter $queryString
    Set-TaskRestartAfter -task $uninstallTask -restartAfter $restartAfterMinutesIfRequired
    $uninstallTaskId = $oTasks.AddTask($uninstallTask)
    Write-Done

    Write-Stage -stage $creatingInstallTaskAction
    $installTaskJson = ConvertFrom-Json $installTaskTemplate
    $installTask = Convert-JsonToKlakaut $installTaskJson
    Set-TaskDisplayName -task $installTask -displayName $installTaskName
    if ($kesCloudInstallationAccount)
    {
        Set-TaskAccount -task $installTask -oTasks $oTasks -accountName $kesCloudInstallationAccount -accountPassword $kesCloudInstallationPassword
    }
    Set-TaskInstallationPackage -task $installTask -packageId $packageId
    Set-TaskQuery -task $installTask -queryId $queryId -queryName $queryName -queyFilter $queryString
    $installTaskId = $oTasks.AddTask($installTask)
    Write-Done

    Write-Host
    Write-Host $(if ($isDomain) { $domainStartTaskPrompt } else { $noDomainStartTaskPrompt })
    $reply = Read-PromptReply -promptMessage $startTaskPromptYesNo -replyRegEx "[yYnN]"
    Write-Host
    if ($reply -match "[yY]")
    {
        Write-Stage -stage $startingUninstallTaskAction 
        $oTasks.RunTask($uninstallTaskId)
        Write-Done
        Write-Host
        Write-Host $(if ($isDomain) { $domainFinalMessage } else { $noDomainFinalMessage })
    }
    else
    {
        Write-Host $(if ($isDomain) { $domainRunManuallyMessage } else { $noDomainRunManuallyMessage })
    }
}
catch
{
    $e = $_.Exception
    $msg = $e.Message
    while ($e.InnerException)
    {
        $e = $e.InnerException
        $msg += "`n" + $e.Message
    }

    Write-Host $msg -ForegroundColor Red
}
finally
{
    Write-Host
    Read-Host $scriptCompletedMessage

    if ($kscConnection)
    {
        $kscConnection.Disconnect()
        $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($kscConnection)
    }
}