Skip to content

Commit

Permalink
Merge pull request #104 from craigcomstock/ENT-12173-windows-capabili…
Browse files Browse the repository at this point in the history
…ties-optional-features

ENT-12173: Add windows-capabilities and windows-optional-features modules
  • Loading branch information
craigcomstock authored Oct 4, 2024
2 parents 33ed057 + bd14392 commit 9daca3b
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 0 deletions.
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)
{
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::
"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),
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"),
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";
}

0 comments on commit 9daca3b

Please sign in to comment.