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

ENT-12173: Add windows-capabilities and windows-optional-features modules #104

Merged
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
27 changes: 27 additions & 0 deletions cfbs.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,33 @@
"bundles uninstall_rsh_server",
"policy_files services/cfbs/modules/uninstall-rsh-server/uninstall-rsh-server.cf"
]
},
"windows-capability": {
"description": "Manage and inventory Windows Capabilities.",
"subdirectory": "management/windows-capability",
"steps": [
"directory ./ services/cfbs/windows-capability/",
"policy_files services/cfbs/windows-capability/",
"bundles windows_capability"
]
},
"windows-openssh-server": {
"description": "Optionally install Windows OpenSSH Server.",
"subdirectory": "software/windows",
"steps": [
"copy windows-openssh-server.cf services/cfbs/software/windows/windows-openssh-server.cf",
"policy_files services/cfbs/software/windows/windows-openssh-server.cf",
"bundles windows_openssh_server"
]
},
"windows-optional-feature": {
"description": "Manage and inventory Windows Optional Features.",
"subdirectory": "management/windows-optional-feature",
"steps": [
"directory ./ services/cfbs/windows-optional-feature/",
"policy_files services/cfbs/windows-optional-feature/",
"bundles windows_optional_feature"
]
}
}
}
70 changes: 70 additions & 0 deletions management/windows-capability/windows-capability.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
bundle agent windows_capability_installed(capability_name)
craigcomstock marked this conversation as resolved.
Show resolved Hide resolved
{
methods:
"Installed" usebundle => windows_capability:_windows_capability_state("${capability_name}", "Installed");
}
bundle agent windows_optionial_capability_notpresent(capability_name)
{
methods:
"NotPresent" usebundle => windows_capability:_windows_capability_state("${capability_name}", "NotPresent");
}

bundle agent windows_capability
{
methods:
windows.!data:disable_windows_capability_inventory::
craigcomstock marked this conversation as resolved.
Show resolved Hide resolved
"windows_capability:_inventory";
}

body file control
{
namespace => "windows_capability";
}

# https://learn.microsoft.com/en-us/powershell/module/dism/get-windowscapability?view=windowsserver2022-ps
# https://learn.microsoft.com/en-us/powershell/module/dism/remove-windowscapability?view=windowsserver2022-ps
# https://learn.microsoft.com/en-us/powershell/module/dism/add-windowscapability?view=windowsserver2022-ps
bundle agent _inventory
{
vars:
windows::
"cache_file" string => "${sys.statedir}${const.dirsep}${this.namespace}_cache.csv";
"command" string => "Get-WindowsCapability -Online | ConvertTo-Csv -notypeinformation | select-object -skip 1 | Set-Content -Path '${cache_file}'";

"csv" data => readcsv("${cache_file}");
"i" slist => getindices("csv");
"${this.namespace}[${i}]" string => "${csv[${i}][0]}:${csv[${i}][1]}",
meta => { "inventory", "attribute_name=Windows Capability" };

files:
"${cache_file}"
file_select => default:days_old(1),
craigcomstock marked this conversation as resolved.
Show resolved Hide resolved
delete => default:tidy;

commands:
windows::
"${command}"
if => not(fileexists("${cache_file}")),
contain => default:powershell;
}


bundle agent _windows_capability_state(capability_name, desired_state)
{
vars:
"operation" string => ifelse(strcmp("${desired_state}", "Installed"), "Add", "Remove");
classes:
windows::
"state_not_ok" expression => returnszero("if((Get-WindowsCapability -Online -Name ${capability_name} | select-object -expandproperty state) -ne '${desired_state}'){exit 0}else{exit 1}", "powershell");

commands:
windows.state_not_ok::
"${operation}-WindowsCapability -Online -Name ${capability_name}"
classes => default:results("bundle", "state"),
contain => default:powershell;

files:
windows.state_repaired::
"${_inventory.cache_file}"
delete => default:tidy;
}
73 changes: 73 additions & 0 deletions management/windows-optional-feature/windows-optional-feature.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# https://learn.microsoft.com/en-us/powershell/module/dism/get-windowsoptionalfeature?view=windowsserver2022-ps
# https://learn.microsoft.com/en-us/powershell/module/dism/disable-windowsoptionalfeature?view=windowsserver2022-ps
# https://learn.microsoft.com/en-us/powershell/module/dism/enable-windowsoptionalfeature?view=windowsserver2022-ps
# https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v#enable-hyper-v-using-powershell

bundle agent windows_optional_feature_enabled( feature_name )
{
methods:
"Enabled" usebundle => windows_optional_feature:_promise_state("${feature_name}", "Enabled");
}

bundle agent windows_optional_feature_disabled( feature_name )
{
methods:
"Disabled" usebundle => windows_optional_feature:_promise_state("${feature_name}", "Disabled");
}

bundle agent windows_optional_feature
{
methods:
windows.!data:disable_windows_optional_feature_inventory::
"windows_optional_feature:_inventory";
}

body file control
{
namespace => "windows_optional_feature";
}

bundle agent _inventory
{
vars:
windows::
"cache_file" string => "${sys.statedir}${const.dirsep}${this.namespace}_cache.csv";
"command" string => "Get-WindowsOptionalFeature -Online | ConvertTo-Csv -notypeinformation | select-object -skip 1 | Set-Content -Path '${cache_file}'";
"csv" data => readcsv("${cache_file}");
"i" slist => getindices("csv");
"${this.namespace}[${i}]" string => "${csv[${i}][0]}:${csv[${i}][1]}",
meta => { "inventory", "attribute_name=Windows Optional Features" };

files:
"${cache_file}"
file_select => default:days_old(1),
delete => default:tidy;

commands:
windows::
"${command}"
if => not(fileexists("${cache_file}")),
contain => default:powershell;
}

bundle agent _promise_state(feature_name, desired_state)
{
vars:
"operation" string => ifelse(strcmp("${desired_state}", "Enabled"), "Enable", "Disable");
classes:
windows::
"state_not_ok" expression => returnszero( "if((Get-WindowsOptionalFeature -Online -FeatureName ${feature_name} | select-object -expandproperty state) -ne '${state_name}'){exit 0}else{exit 1}", "powershell");
commands:
windows.state_not_ok::
# -All enables parent features if need be
"${operation}-WindowsOptionalFeature -Online -FeatureName ${feature_name} -NoRestart -All"
contain => default:powershell,
classes => default:results("bundle", "state");
# -NoRestart so that we don't wait forever for a Yes reply from a user
# then if we ran this command due to needing to, restart below.

files:
windows.state_repaired::
"${_inventory.cache_file}"
delete => default:tidy;
}
29 changes: 29 additions & 0 deletions software/windows/windows-openssh-server.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
bundle agent windows_openssh_server
{
methods:
data:openssh_server_installed::
"openssh_server_installed";
}

bundle agent windows_openssh_server_installed
{
methods:
windows::
"Add OpenSSH.Server Capability"
# NOTE: this version "0.0.1.0" is not the actual version but rather a static number that is mysterious to me.
# the actual installed version will be the "latest"
usebundle => windows_capability_installed("OpenSSH.Server~~~~0.0.1.0"),
craigcomstock marked this conversation as resolved.
Show resolved Hide resolved
classes => classes_generic("openssh");

services:
windows.openssh_ok::
"sshd"
service_policy => "start",
service_method => windows_openssh_service_method;
}

body service_method windows_openssh_service_method
{
service_type => "windows";
service_autostart_policy => "boot_time";
}