Skip to content

Commit ca7363d

Browse files
makanakoelnTimotheusBachinger
authored andcommitted
19754: FIX Fix Windows agent install & register for PowerShell
CMK-33860 Change-Id: Ia1f01670c50321320b543f1fa9527da1be73f5de (cherry picked from commit 8d4ddd1)
1 parent e9a232e commit ca7363d

7 files changed

Lines changed: 165 additions & 12 deletions

File tree

.werks/19754.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[//]: # (werk v3)
2+
# Fix Windows agent install & register for PowerShell
3+
4+
key | value
5+
---------- | ---
6+
date | 2026-04-22T10:05:25.191464+00:00
7+
version | 2.5.0
8+
class | fix
9+
edition | community
10+
component | wato
11+
level | 1
12+
compatible | yes
13+
14+
Previously, the "Install & register agent" slide-out on Windows had two annoying quirks:
15+
16+
- The registration command failed in PowerShell with a parser error, while it worked in Command Prompt.
17+
- The installation prompted for interactive confirmation instead of running unattended.
18+
19+
Both are now fixed. The slide-out offers a PowerShell/Command Prompt selector in the "Download and install" and "Register agent" steps. Pick your shell once — the selection carries over to both steps and to the troubleshooting fallback. PowerShell is preselected.
20+
21+
The MSI install now runs silently, so the flow completes without extra clicks.
22+
23+
See also Werk #19505, which earlier addressed related compatibility issues in the same slide-out but did not cover the registration command.

cmk/gui/utils/agent_commands.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,20 @@
3737
' --data-urlencode "os_type=windows_msi"'
3838
)
3939

40-
WINDOWS_AGENT_INSTALL_CMD = "msiexec /i check-mk-agent_{version}.msi"
40+
WINDOWS_AGENT_DOWNLOAD_CMD_POWERSHELL = (
41+
"Invoke-WebRequest `\n"
42+
' -Uri "{{{{SERVER}}}}/{{{{SITE}}}}/check_mk/api/internal/domain-types/agent/actions/download_by_token/invoke?os_type=windows_msi" `\n'
43+
' -OutFile "check-mk-agent_{version}.msi" `\n'
44+
' -Method "GET" `\n'
45+
" -Headers @{{\n"
46+
' "Accept" = "application/octet-stream";\n'
47+
' "Authorization" = "CMK-TOKEN 0:[AGENT_DOWNLOAD_OTT]"\n'
48+
" }}"
49+
)
50+
51+
WINDOWS_AGENT_INSTALL_CMD = "msiexec /i check-mk-agent_{version}.msi /quiet /norestart"
52+
53+
WINDOWS_AGENT_INSTALL_CMD_POWERSHELL = 'Start-Process msiexec.exe -ArgumentList "/i `"$PWD\\check-mk-agent_{version}.msi`" /quiet /norestart" -Wait'
4154

4255
LINUX_DEBIAN_AGENT_INSTALL_CMD = """curl -o check-mk-agent_{version}-1_all.deb -fJG \\
4356
'{{{{SERVER}}}}/{{{{SITE}}}}/check_mk/api/internal/domain-types/agent/actions/download_by_token/invoke' \\
@@ -60,7 +73,9 @@ def build_agent_install_cmds(
6073
) -> AgentInstallCmds:
6174
return AgentInstallCmds(
6275
windows_download=WINDOWS_AGENT_DOWNLOAD_CMD.format(version=version),
76+
windows_download_powershell=WINDOWS_AGENT_DOWNLOAD_CMD_POWERSHELL.format(version=version),
6377
windows=WINDOWS_AGENT_INSTALL_CMD.format(version=version),
78+
windows_powershell=WINDOWS_AGENT_INSTALL_CMD_POWERSHELL.format(version=version),
6479
linux_deb=LINUX_DEBIAN_AGENT_INSTALL_CMD.format(version=version),
6580
linux_rpm=LINUX_RPM_AGENT_INSTALL_CMD.format(version=version),
6681
)
@@ -74,6 +89,14 @@ def build_agent_install_cmds(
7489
" --user agent_registration"
7590
)
7691

92+
WINDOWS_AGENT_REGISTRATION_CMD_POWERSHELL = (
93+
'& "C:\\Program Files (x86)\\checkmk\\service\\cmk-agent-ctl.exe" register'
94+
" --hostname {{HOSTNAME}}"
95+
" --server {{SERVER}}"
96+
" --site {{SITE}}"
97+
" --user agent_registration"
98+
)
99+
77100
LINUX_REGISTRATION_CMD = """sudo cmk-agent-ctl register \\
78101
--hostname {{HOSTNAME}} \\
79102
--server {{SERVER}} \\
@@ -96,6 +119,7 @@ def build_agent_install_cmds(
96119
def build_agent_registration_cmds() -> AgentRegistrationCmds:
97120
return AgentRegistrationCmds(
98121
windows=WINDOWS_AGENT_REGISTRATION_CMD,
122+
windows_powershell=WINDOWS_AGENT_REGISTRATION_CMD_POWERSHELL,
99123
linux=LINUX_REGISTRATION_CMD,
100124
aix=AIX_REGISTRATION_CMD,
101125
solaris=SOLARIS_REGISTRATION_CMD,

packages/cmk-frontend-vue/src/mode-host/agent-connection-test/components/AgentSlideOut.vue

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ref, watch } from 'vue'
88
99
import usei18n from '@/lib/i18n'
1010
import type { TranslatedString } from '@/lib/i18nString'
11+
import usePersistentRef from '@/lib/usePersistentRef'
1112
1213
import CmkAlertBox from '@/components/CmkAlertBox.vue'
1314
import CmkButton from '@/components/CmkButton.vue'
@@ -62,6 +63,10 @@ const model = ref(sessionStorage.getItem('slideInModelState') || packageFormatDe
6263
sessionStorage.removeItem('slideInModelState')
6364
sessionStorage.removeItem('slideInTabState')
6465
66+
const selectedVariantId = usePersistentRef<string>('slideInSelectedVariantId', 'powershell', (v) =>
67+
typeof v === 'string' ? v : 'powershell'
68+
)
69+
6570
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6671
declare const cmk: any
6772
function saveHostAction() {
@@ -216,7 +221,32 @@ function getInitStep() {
216221
/>
217222
</div>
218223
<template v-if="ott !== null">
219-
<template v-if="tab.installDownloadCmd">
224+
<template v-if="tab.installCmdVariants && tab.installCmdVariants.length > 1">
225+
<CmkToggleButtonGroup
226+
v-model="selectedVariantId"
227+
class="shell-toggle"
228+
:options="
229+
tab.installCmdVariants.map((v) => ({ label: v.label, value: v.id }))
230+
"
231+
/>
232+
<template v-for="variant in tab.installCmdVariants" :key="variant.id">
233+
<template v-if="variant.id === selectedVariantId">
234+
<CmkCode
235+
:title="_t('Download the agent')"
236+
:code_txt="installCmdWithToken(variant.downloadCmd || '')"
237+
class="code"
238+
width="fill"
239+
/>
240+
<CmkCode
241+
:title="_t('Install the agent')"
242+
:code_txt="variant.installCmd"
243+
class="code"
244+
width="fill"
245+
/>
246+
</template>
247+
</template>
248+
</template>
249+
<template v-else-if="tab.installDownloadCmd">
220250
<CmkCode
221251
:title="_t('Download agent')"
222252
:code_txt="installCmdWithToken(tab.installDownloadCmd)"
@@ -292,6 +322,7 @@ function getInitStep() {
292322
</CmkWizardStep>
293323

294324
<RegisterAgent
325+
v-model:selected-variant-id="selectedVariantId"
295326
:index="3"
296327
:is-completed="() => currentStep > 3 || !tab.registrationMsg"
297328
:tab="tab"
@@ -368,6 +399,11 @@ button.all_agents {
368399
width: 100%;
369400
}
370401
402+
.shell-toggle {
403+
margin-top: var(--dimension-5);
404+
margin-bottom: var(--dimension-5);
405+
}
406+
371407
.register-heading-row {
372408
display: flex;
373409
flex-direction: row;

packages/cmk-frontend-vue/src/mode-host/agent-connection-test/components/AgentSlideOutContent.vue

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,36 @@ const tabs = computed<AgentSlideOutTabs[]>(() => [
9090
),
9191
installDownloadCmd: replaceMacros(props.agentInstallCmds.windows_download, false),
9292
installCmd: replaceMacros(props.agentInstallCmds.windows, false),
93+
installCmdVariants: [
94+
{
95+
id: 'powershell',
96+
label: 'PowerShell',
97+
downloadCmd: replaceMacros(props.agentInstallCmds.windows_download_powershell, false),
98+
installCmd: replaceMacros(props.agentInstallCmds.windows_powershell, false)
99+
},
100+
{
101+
id: 'cmd',
102+
label: 'Command Prompt',
103+
downloadCmd: replaceMacros(props.agentInstallCmds.windows_download, false),
104+
installCmd: replaceMacros(props.agentInstallCmds.windows, false)
105+
}
106+
],
93107
registrationMsg: _t(
94108
'After you have installed the agent, run this command on your Windows host to register the Checkmk agent controller. Please make sure to run this command with sufficient permissions (e.g. "Run as Administrator").'
95109
),
96-
registrationCmd: replaceMacros(props.agentRegistrationCmds.windows, true)
110+
registrationCmd: replaceMacros(props.agentRegistrationCmds.windows, true),
111+
registrationCmdVariants: [
112+
{
113+
id: 'powershell',
114+
label: 'PowerShell',
115+
cmd: replaceMacros(props.agentRegistrationCmds.windows_powershell, true)
116+
},
117+
{
118+
id: 'cmd',
119+
label: 'Command Prompt',
120+
cmd: replaceMacros(props.agentRegistrationCmds.windows, true)
121+
}
122+
]
97123
},
98124
{
99125
id: 'linux',

packages/cmk-frontend-vue/src/mode-host/agent-connection-test/components/steps/RegisterAgent.vue

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import CmkCode from '@/components/CmkCode.vue'
1414
import CmkCollapsible from '@/components/CmkCollapsible'
1515
import CmkCollapsibleTitle from '@/components/CmkCollapsible/CmkCollapsibleTitle.vue'
1616
import CmkIndent from '@/components/CmkIndent.vue'
17+
import CmkToggleButtonGroup from '@/components/CmkToggleButtonGroup.vue'
1718
import { CmkWizardButton } from '@/components/CmkWizard'
1819
import CmkWizardStep from '@/components/CmkWizard/CmkWizardStep.vue'
1920
import { getWizardContext } from '@/components/CmkWizard/utils.ts'
@@ -36,21 +37,29 @@ const props = defineProps<{
3637
agentReceiverPortIsDefault: boolean
3738
}>()
3839
40+
const selectedVariantId = defineModel<string>('selectedVariantId', { default: '' })
3941
const emit = defineEmits(['close'])
4042
const context = getWizardContext()
4143
const ott = ref<string | null | Error>(null)
4244
const collapsibleOpen = ref<boolean>(false)
4345
44-
const regAgentOttCmd = computed(() => {
45-
if (props.tab.registrationCmd) {
46-
if (ott.value && !(ott.value instanceof Error)) {
47-
return props.tab.registrationCmd?.replace('--user agent_registration', `--ott 0:${ott.value}`)
48-
}
46+
const activeRegistrationCmd = computed<string | undefined>(() => {
47+
const variants = props.tab.registrationCmdVariants
48+
if (variants && variants.length > 0) {
49+
return variants.find((v) => v.id === selectedVariantId.value)?.cmd ?? variants[0]!.cmd
50+
}
51+
return props.tab.registrationCmd
52+
})
4953
50-
return props.tab.registrationCmd
51-
} else {
54+
const regAgentOttCmd = computed(() => {
55+
const cmd = activeRegistrationCmd.value
56+
if (!cmd) {
5257
return ''
5358
}
59+
if (ott.value && !(ott.value instanceof Error)) {
60+
return cmd.replace('--user agent_registration', `--ott 0:${ott.value}`)
61+
}
62+
return cmd
5463
})
5564
5665
function reset() {
@@ -64,7 +73,7 @@ function reset() {
6473
</template>
6574
<template #content>
6675
<div v-if="context.isSelected(index)">
67-
<div v-if="tab.registrationMsg && tab.registrationCmd">
76+
<div v-if="tab.registrationMsg && (tab.registrationCmd || tab.registrationCmdVariants)">
6877
<div class="register-heading-row">
6978
<CmkParagraph>
7079
{{
@@ -87,6 +96,12 @@ function reset() {
8796
:description="_t('This requires the generation of a registration token.')"
8897
/>
8998
<template v-if="ott !== null">
99+
<CmkToggleButtonGroup
100+
v-if="tab.registrationCmdVariants && tab.registrationCmdVariants.length > 1"
101+
v-model="selectedVariantId"
102+
class="mh-register-agent__shell-toggle"
103+
:options="tab.registrationCmdVariants.map((v) => ({ label: v.label, value: v.id }))"
104+
/>
90105
<CmkParagraph>{{ tab.registrationMsg }}</CmkParagraph>
91106
<CmkCode :code_txt="regAgentOttCmd" class="code" width="fill" />
92107
<CmkAlertBox v-if="agentReceiverPortIsDefault" variant="warning" size="small">
@@ -131,7 +146,13 @@ function reset() {
131146
<a :href="userSettingsUrl" target="_blank"> {{ _t('agent_registration user') }}</a>
132147
{{ _t(`and paste it into the terminal to continue the registration.`) }}
133148
</CmkParagraph>
134-
<CmkCode :code_txt="tab.registrationCmd ?? ''" class="code" width="fill" />
149+
<CmkToggleButtonGroup
150+
v-if="tab.registrationCmdVariants && tab.registrationCmdVariants.length > 1"
151+
v-model="selectedVariantId"
152+
class="mh-register-agent__shell-toggle"
153+
:options="tab.registrationCmdVariants.map((v) => ({ label: v.label, value: v.id }))"
154+
/>
155+
<CmkCode :code_txt="activeRegistrationCmd ?? ''" class="code" width="fill" />
135156
</CmkIndent>
136157
</CmkCollapsible>
137158
</template>
@@ -154,4 +175,9 @@ function reset() {
154175
.mh-register-agent__panel {
155176
max-width: 650px;
156177
}
178+
179+
.mh-register-agent__shell-toggle {
180+
margin-top: var(--dimension-5);
181+
margin-bottom: var(--dimension-5);
182+
}
157183
</style>

packages/cmk-frontend-vue/src/mode-host/agent-connection-test/lib/type_def.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ export type PackageOption = {
1313
}
1414
export type PackageOptions = PackageOption[]
1515

16+
export interface RegistrationCmdVariant {
17+
id: string
18+
label: string
19+
cmd: string
20+
}
21+
22+
export interface InstallCmdVariant {
23+
id: string
24+
label: string
25+
downloadCmd?: string
26+
installCmd: string
27+
}
28+
1629
export interface AgentSlideOutTabs {
1730
id: string
1831
title: string
@@ -22,8 +35,10 @@ export interface AgentSlideOutTabs {
2235
installDebCmd?: string
2336
installRpmCmd?: string
2437
installTgzCmd?: string | undefined
38+
installCmdVariants?: InstallCmdVariant[]
2539
registrationMsg?: TranslatedString
2640
registrationCmd?: string
41+
registrationCmdVariants?: RegistrationCmdVariant[]
2742
installUrl?: InstallUrl | undefined
2843
toggleButtonOptions?: PackageOptions
2944
}

packages/cmk-shared-typing/source/agent_slideout.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
"type": "object",
3030
"properties": {
3131
"windows_download": { "type": "string" },
32+
"windows_download_powershell": { "type": "string" },
3233
"windows": { "type": "string" },
34+
"windows_powershell": { "type": "string" },
3335
"linux_deb": { "type": "string" },
3436
"linux_rpm": { "type": "string" },
3537
"linux_tgz": { "type": "string" },
@@ -42,6 +44,7 @@
4244
"type": "object",
4345
"properties": {
4446
"windows": { "type": "string" },
47+
"windows_powershell": { "type": "string" },
4548
"linux": { "type": "string" },
4649
"solaris": { "type": "string" },
4750
"aix": { "type": "string" }

0 commit comments

Comments
 (0)