Update cookbooks and add wordpress cookbook

This commit is contained in:
Greg Karékinian
2016-02-19 18:09:49 +01:00
parent 9ba973e3ac
commit 820b0ab3f8
606 changed files with 22421 additions and 14084 deletions

View File

@@ -1,320 +1,362 @@
windows Cookbook CHANGELOG
=======================
This file is used to list changes made in each version of the windows cookbook.
v1.36.6 (2014-12-18)
--------------------
- reverting all chef_gem compile_time work
v1.36.5 (2014-12-18)
--------------------
- Fix zipfile provider
v1.36.4 (2014-12-18)
--------------------
- Fix Chef chef_gem with Chef::Resource::ChefGem.method_defined?(:compile_time)
v1.36.3 (2014-12-18)
--------------------
- Fix Chef chef_gem below 12.1.0
v1.36.2 (2014-12-17)
--------------------
- Being explicit about usage of the chef_gem's compile_time property.
- Eliminating future deprecation warnings in Chef 12.1.0
v1.36.1 (2014-12-17)
--------------------
- [PR 160](https://github.com/chef-cookbooks/windows/pull/160) - Fix Chef 11.10 / versions without windows_package in core
v1.36.0 (2014-12-16)
--------------------
- [PR 145](https://github.com/chef-cookbooks/windows/pull/145) - do not fail on non-existant task
- [PR 144](https://github.com/chef-cookbooks/windows/pull/144) - Add a zip example to the README
- [PR 110](https://github.com/chef-cookbooks/windows/pull/110) - More zip documentation
- [PR 148](https://github.com/chef-cookbooks/windows/pull/148) - Add an LWRP for font installation
- [PR 151](https://github.com/chef-cookbooks/windows/pull/151) - Fix windows_package on Chef 12, add integration tests
- [PR 129](https://github.com/chef-cookbooks/windows/pull/129) - Add enable/disable actions to task LWRP
- [PR 115](https://github.com/chef-cookbooks/windows/pull/115) - require Chef::Mixin::PowershellOut before using it
- [PR 88](https://github.com/chef-cookbooks/windows/pull/88) - Code 1003 from servermanagercmd.exe is valid
v1.34.8 (2014-10-31)
--------------------
- [Issue 137](https://github.com/chef-cookbooks/windows/issues/137) - windows_path resource breaks with ruby 2.x
v1.34.6 (2014-09-22)
--------------------
- [Chef-2009](https://github.com/chef/chef/issues/2009) - Patch to work around a regression in [Chef](https://github.com/chef/chef)
v1.34.2 (2014-08-12)
--------------------
- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Remove rubygems / Internet wmi-lite dependency (PR #108)
v1.34.0 (2014-08-04)
--------------------
- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Use wmi-lite to fix Chef 11.14.2 break in rdp-ruby-wmi dependency
v1.32.1 (2014-07-15)
--------------------
- Fixes broken cookbook release
v1.32.0 (2014-07-11)
--------------------
- Add ChefSpec resource methods to allow notification testing (@sneal)
- Add use_inline_resources to providers (@micgo)
- [COOK-4728] - Allow reboot handler to be used as an exception handler
- [COOK-4620] - Ensure win_friendly_path doesn't error out when ALT_SEPARATOR is nil
v1.31.0 (2014-05-07)
--------------------
- [COOK-2934] - Add windows_feature support for 2 new DISM attributes: all, source
v1.30.2 (2014-04-02)
--------------------
- [COOK-4414] - Adding ChefSpec matchers
v1.30.0 (2014-02-14)
--------------------
- [COOK-3715] - Unable to create a startup task with no login
- [COOK-4188] - Add powershell_version method to return Powershell version
v1.12.8 (2014-01-21)
--------------------
- [COOK-3988] Don't unescape URI before constructing it.
v1.12.6 (2014-01-03)
--------------------
- [COOK-4168] Circular dep on powershell - moving powershell libraries into windows. removing dependency on powershell
v1.12.4
-------
Fixing depend/depends typo in metadata.rb
v1.12.2
-------
### Bug
- **[COOK-4110](https://tickets.chef.io/browse/COOK-4110)** - feature_servermanager installed? method regex bug
v1.12.0
-------
### Bug
- **[COOK-3793](https://tickets.chef.io/browse/COOK-3793)** - parens inside parens of README.md don't render
### New Feature
- **[COOK-3714](https://tickets.chef.io/browse/COOK-3714)** - Powershell features provider and delete support.
v1.11.0
-------
### Improvement
- **[COOK-3724](https://tickets.chef.io/browse/COOK-3724)** - Rrecommend built-in resources over cookbook resources
- **[COOK-3515](https://tickets.chef.io/browse/COOK-3515)** - Remove unprofessional comment from library
- **[COOK-3455](https://tickets.chef.io/browse/COOK-3455)** - Add Windows Server 2012R2 to windows cookbook version helper
### Bug
- **[COOK-3542](https://tickets.chef.io/browse/COOK-3542)** - Fix an issue where `windows_zipfile` fails with LoadError
- **[COOK-3447](https://tickets.chef.io/browse/COOK-3447)** - Allow Overriding Of The Default Reboot Timeout In windows_reboot_handler
- **[COOK-3382](https://tickets.chef.io/browse/COOK-3382)** - Allow windows_task to create `on_logon` tasks
- **[COOK-2098](https://tickets.chef.io/browse/COOK-2098)** - Fix and issue where the `windows_reboot` handler is ignoring the reboot time
### New Feature
- **[COOK-3458](https://tickets.chef.io/browse/COOK-3458)** - Add support for `start_date` and `start_time` in `windows_task`
v1.10.0
-------
### Improvement
- [COOK-3126]: `windows_task` should support the on start frequency
- [COOK-3127]: Support the force option on task create and delete
v1.9.0
------
### Bug
- [COOK-2899]: windows_feature fails when a feature install requires a
reboot
- [COOK-2914]: Foodcritic failures in Cookbooks
- [COOK-2983]: windows cookbook has foodcritic failures
### Improvement
- [COOK-2686]: Add Windows Server 2012 to version.rb so other
depending chef scripts can detect Windows Server 2012
v1.8.10
-------
When using Windows qualified filepaths (C:/foo), the #absolute? method
for URI returns true, because "C" is the scheme.
This change checks that the URI is http or https scheme, so it can be
passed off to remote_file appropriately.
* [COOK-2729] - allow only http, https URI schemes
v1.8.8
------
* [COOK-2729] - helper should use URI rather than regex and bare string
v1.8.6
------
* [COOK-968] - `windows_package` provider should gracefully handle paths with spaces
* [COOK-222] - `windows_task` resource does not declare :change action
* [COOK-241] - Windows cookbook should check for redefined constants
* [COOK-248] - Windows package install type is case sensitive
v1.8.4
------
* [COOK-2336] - MSI That requires reboot returns with RC 3010 and
causes chef run failure
* [COOK-2368] - `version` attribute of the `windows_package` provider
should be documented
v1.8.2
------
**Important**: Use powershell in nodes expanded run lists to ensure
powershell is downloaded, as powershell has a dependency on this
cookbook; v1.8.0 created a circular dependency.
* [COOK-2301] - windows 1.8.0 has circular dependency on powershell
v1.8.0
------
* [COOK-2126] - Add checksum attribute to `windows_zipfile`
* [COOK-2142] - Add printer and `printer_port` LWRPs
* [COOK-2149] - Chef::Log.debug Windows Package command line
* [COOK-2155] -`windows_package` does not send checksum to
`cached_file` in `installer_type`
v1.7.0
------
* [COOK-1745] - allow for newer versions of rubyzip
v1.6.0
------
* [COOK-2048] - undefined method for Falseclass on task :change when
action is :nothing (and task doesn't exist)
* [COOK-2049] - Add `windows_pagefile` resource
v1.5.0
------
* [COOK-1251] - Fix LWRP "NotImplementedError"
* [COOK-1921] - Task LWRP will return true for resource exists when no
other scheduled tasks exist
* [COOK-1932] - Include :change functionality to windows task lwrp
v1.4.0:
------
* [COOK-1571] - `windows_package` resource (with msi provider) does not
accept spaces in filename
* [COOK-1581] - Windows cookbook needs a scheduled tasks LWRP
* [COOK-1584] - `windows_registry` should support all registry types
v1.3.4
------
* [COOK-1173] - `windows_registry` throws Win32::Registry::Error for
action :remove on a nonexistent key
* [COOK-1182] - windows package sets start window title instead of
quoting a path
* [COOK-1476] - zipfile lwrp should support :zip action
* [COOK-1485] - package resource fails to perform install correctly
when "source" contains quote
* [COOK-1519] - add action :remove for path lwrp
v1.3.2
------
* [COOK-1033] - remove the `libraries/ruby_19_patches.rb` file which
causes havoc on non-Windows systems.
* [COOK-811] - add a timeout parameter attribute for `windows_package`
v1.3.0
------
* [COOK-1323] - Update for changes in Chef 0.10.10.
- Setting file mode doesn't make sense on Windows (package provider
- and `reboot_handler` recipe)
- Prefix ::Win32 to avoid namespace collision with Chef::Win32
- (`registry_helper` library)
- Use chef_gem instead of gem_package so gems get installed correctly
under the Ruby environment Chef runs in (reboot_handler recipe,
zipfile provider)
v1.2.12
-------
* [COOK-1037] - specify version for rubyzip gem
* [COOK-1007] - `windows_feature` does not work to remove features with
dism
* [COOK-667] - shortcut resource + provider for Windows platforms
v1.2.10
-------
* [COOK-939] - add `type` parameter to `windows_registry` to allow binary registry keys.
* [COOK-940] - refactor logic so multiple values get created.
v1.2.8
------
* FIX: Older Windows (Windows Server 2003) sometimes return 127 on successful forked commands
* FIX: `windows_package`, ensure we pass the WOW* registry redirection flags into reg.open
v1.2.6
------
* patch to fix [CHEF-2684], Open4 is named Open3 in Ruby 1.9
* Ruby 1.9's Open3 returns 0 and 42 for successful commands
* retry keyword can only be used in a rescue block in Ruby 1.9
v1.2.4
------
* `windows_package` - catch Win32::Registry::Error that pops up when searching certain keys
v1.2.2
------
* combined numerous helper libarires for easier sharing across libaries/LWRPs
* renamed Chef::Provider::WindowsFeature::Base file to the more descriptive `feature_base.rb`
* refactored `windows_path` LWRP
* :add action should MODIFY the the underlying ENV variable (vs CREATE)
* deleted greedy :remove action until it could be made more idempotent
* added a `windows_batch` resource/provider for running batch scripts remotely
v1.2.0
------
* [COOK-745] gracefully handle required server restarts on Windows platform
* WindowsRebootHandler for requested and pending reboots
* `windows_reboot` LWRP for requesting (receiving notifies) reboots
* `reboot_handler` recipe for enabling WindowsRebootHandler as a report handler
* [COOK-714] Correct initialize misspelling
* RegistryHelper - new `get_values` method which returns all values for a particular key.
v1.0.8
------
* [COOK-719] resource/provider for managing windows features
* [COOK-717] remove `windows_env_vars` resource as env resource exists in core chef
* new `Windows::Version` helper class
* refactored `Windows::Helper` mixin
v1.0.6
------
* added `force_modify` action to `windows_registry` resource
* add `win_friendly_path` helper
* re-purpose default recipe to install useful supporting windows related gems
v1.0.4
------
* [COOK-700] new resources and improvements to the `windows_registry` provider (thanks Paul Morton!)
* Open the registry in the bitednes of the OS
* Provide convenience methods to check if keys and values exit
* Provide convenience method for reading registry values
* NEW - `windows_auto_run` resource/provider
* NEW - `windows_env_vars` resource/provider
* NEW - `windows_path` resource/provider
* re-write of the `windows_package` logic for determining current installed packages
* new checksum attribute for `windows_package` resource...useful for remote packages
v1.0.2
------
* [COOK-647] account for Wow6432Node registry redirecter
* [COOK-656] begin/rescue on win32/registry
v1.0.0
------
* [COOK-612] initial release
windows Cookbook CHANGELOG
=======================
This file is used to list changes made in each version of the windows cookbook.
v1.38.4
--------------------
- [PR 295](https://github.com/chef-cookbooks/windows/pull/295) - Escape `http_acl` username
- [PR 293](https://github.com/chef-cookbooks/windows/pull/293) - Separating assignments to `code_script` and `guard_script` as they should be different scripts and not hold the same reference
- [Issue 298](https://github.com/chef-cookbooks/windows/issues/298) - `windows_certificate_binding` is ignoring `store_name` attribute and always saving to `MY`
- [Issue 296](https://github.com/chef-cookbooks/windows/pull/302) - Fixes `windows_certificate` idempotentcy on chef 11 clients
v1.38.3
--------------------
- Make `windows_task` resource idempotent (double quotes need to be single when comparing)
- [Issue 245](https://github.com/chef-cookbooks/windows/issues/256) - Fix `No resource, method, or local variable named `password' for `Chef::Provider::WindowsTask'` when `interactive_enabled` is `true`
v1.38.2
--------------------
- Lazy-load windows-pr gem library files. Chef 12.5 no longer includes the windows-pr gem. Earlier versions of this cookbook will not compile on Chef 12.5.
v1.38.1 (2015-07-28)
--------------------
- Publishing without extended metadata
v1.38.0 (2015-07-27)
--------------------
- Do not set new_resource.password to nil, Fixes #219, Fixes #220
- Add `windows_certificate` resource #212
- Add `windows_http_acl` resource #214
v1.37.0 (2015-05-14)
--------------------
- fix `windows_package` `Chef.set_resource_priority_array` warning
- update `windows_task` to support tasks in folders
- fix `windows_task` delete action
- replace `windows_task` name attribute with 'task_name'
- add :end action to 'windows_task'
- Tasks created with the `windows_task` resource default to the SYSTEM account
- The force attribute for `windows_task` makes the :create action update the definition.
- `windows_task` :create action will force an update of the task if the user or command differs from the currently configured setting.
- add default provider for `windows_feature`
- add a helper to make sure `WindowsRebootHandler` works in ChefSpec
- added a source and issues url to the metadata for Supermarket
- updated the Gemfile and .kitchen.yml to reflect the latest test-kitchen windows guest support
- started tests using the kitchen-pester verifier
v1.36.6 (2014-12-18)
--------------------
- reverting all chef_gem compile_time work
v1.36.5 (2014-12-18)
--------------------
- Fix zipfile provider
v1.36.4 (2014-12-18)
--------------------
- Fix Chef chef_gem with Chef::Resource::ChefGem.method_defined?(:compile_time)
v1.36.3 (2014-12-18)
--------------------
- Fix Chef chef_gem below 12.1.0
v1.36.2 (2014-12-17)
--------------------
- Being explicit about usage of the chef_gem's compile_time property.
- Eliminating future deprecation warnings in Chef 12.1.0
v1.36.1 (2014-12-17)
--------------------
- [PR 160](https://github.com/chef-cookbooks/windows/pull/160) - Fix Chef 11.10 / versions without windows_package in core
v1.36.0 (2014-12-16)
--------------------
- [PR 145](https://github.com/chef-cookbooks/windows/pull/145) - do not fail on non-existant task
- [PR 144](https://github.com/chef-cookbooks/windows/pull/144) - Add a zip example to the README
- [PR 110](https://github.com/chef-cookbooks/windows/pull/110) - More zip documentation
- [PR 148](https://github.com/chef-cookbooks/windows/pull/148) - Add an LWRP for font installation
- [PR 151](https://github.com/chef-cookbooks/windows/pull/151) - Fix windows_package on Chef 12, add integration tests
- [PR 129](https://github.com/chef-cookbooks/windows/pull/129) - Add enable/disable actions to task LWRP
- [PR 115](https://github.com/chef-cookbooks/windows/pull/115) - require Chef::Mixin::PowershellOut before using it
- [PR 88](https://github.com/chef-cookbooks/windows/pull/88) - Code 1003 from servermanagercmd.exe is valid
v1.34.8 (2014-10-31)
--------------------
- [Issue 137](https://github.com/chef-cookbooks/windows/issues/137) - windows_path resource breaks with ruby 2.x
v1.34.6 (2014-09-22)
--------------------
- [Chef-2009](https://github.com/chef/chef/issues/2009) - Patch to work around a regression in [Chef](https://github.com/chef/chef)
v1.34.2 (2014-08-12)
--------------------
- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Remove rubygems / Internet wmi-lite dependency (PR #108)
v1.34.0 (2014-08-04)
--------------------
- [Issue 99](https://github.com/chef-cookbooks/windows/issues/99) - Use wmi-lite to fix Chef 11.14.2 break in rdp-ruby-wmi dependency
v1.32.1 (2014-07-15)
--------------------
- Fixes broken cookbook release
v1.32.0 (2014-07-11)
--------------------
- Add ChefSpec resource methods to allow notification testing (@sneal)
- Add use_inline_resources to providers (@micgo)
- [COOK-4728] - Allow reboot handler to be used as an exception handler
- [COOK-4620] - Ensure win_friendly_path doesn't error out when ALT_SEPARATOR is nil
v1.31.0 (2014-05-07)
--------------------
- [COOK-2934] - Add windows_feature support for 2 new DISM attributes: all, source
v1.30.2 (2014-04-02)
--------------------
- [COOK-4414] - Adding ChefSpec matchers
v1.30.0 (2014-02-14)
--------------------
- [COOK-3715] - Unable to create a startup task with no login
- [COOK-4188] - Add powershell_version method to return Powershell version
v1.12.8 (2014-01-21)
--------------------
- [COOK-3988] Don't unescape URI before constructing it.
v1.12.6 (2014-01-03)
--------------------
- [COOK-4168] Circular dep on powershell - moving powershell libraries into windows. removing dependency on powershell
v1.12.4
-------
Fixing depend/depends typo in metadata.rb
v1.12.2
-------
### Bug
- **[COOK-4110](https://tickets.chef.io/browse/COOK-4110)** - feature_servermanager installed? method regex bug
v1.12.0
-------
### Bug
- **[COOK-3793](https://tickets.chef.io/browse/COOK-3793)** - parens inside parens of README.md don't render
### New Feature
- **[COOK-3714](https://tickets.chef.io/browse/COOK-3714)** - Powershell features provider and delete support.
v1.11.0
-------
### Improvement
- **[COOK-3724](https://tickets.chef.io/browse/COOK-3724)** - Rrecommend built-in resources over cookbook resources
- **[COOK-3515](https://tickets.chef.io/browse/COOK-3515)** - Remove unprofessional comment from library
- **[COOK-3455](https://tickets.chef.io/browse/COOK-3455)** - Add Windows Server 2012R2 to windows cookbook version helper
### Bug
- **[COOK-3542](https://tickets.chef.io/browse/COOK-3542)** - Fix an issue where `windows_zipfile` fails with LoadError
- **[COOK-3447](https://tickets.chef.io/browse/COOK-3447)** - Allow Overriding Of The Default Reboot Timeout In windows_reboot_handler
- **[COOK-3382](https://tickets.chef.io/browse/COOK-3382)** - Allow windows_task to create `on_logon` tasks
- **[COOK-2098](https://tickets.chef.io/browse/COOK-2098)** - Fix and issue where the `windows_reboot` handler is ignoring the reboot time
### New Feature
- **[COOK-3458](https://tickets.chef.io/browse/COOK-3458)** - Add support for `start_date` and `start_time` in `windows_task`
v1.10.0
-------
### Improvement
- [COOK-3126]: `windows_task` should support the on start frequency
- [COOK-3127]: Support the force option on task create and delete
v1.9.0
------
### Bug
- [COOK-2899]: windows_feature fails when a feature install requires a
reboot
- [COOK-2914]: Foodcritic failures in Cookbooks
- [COOK-2983]: windows cookbook has foodcritic failures
### Improvement
- [COOK-2686]: Add Windows Server 2012 to version.rb so other
depending chef scripts can detect Windows Server 2012
v1.8.10
-------
When using Windows qualified filepaths (C:/foo), the #absolute? method
for URI returns true, because "C" is the scheme.
This change checks that the URI is http or https scheme, so it can be
passed off to remote_file appropriately.
* [COOK-2729] - allow only http, https URI schemes
v1.8.8
------
* [COOK-2729] - helper should use URI rather than regex and bare string
v1.8.6
------
* [COOK-968] - `windows_package` provider should gracefully handle paths with spaces
* [COOK-222] - `windows_task` resource does not declare :change action
* [COOK-241] - Windows cookbook should check for redefined constants
* [COOK-248] - Windows package install type is case sensitive
v1.8.4
------
* [COOK-2336] - MSI That requires reboot returns with RC 3010 and
causes chef run failure
* [COOK-2368] - `version` attribute of the `windows_package` provider
should be documented
v1.8.2
------
**Important**: Use powershell in nodes expanded run lists to ensure
powershell is downloaded, as powershell has a dependency on this
cookbook; v1.8.0 created a circular dependency.
* [COOK-2301] - windows 1.8.0 has circular dependency on powershell
v1.8.0
------
* [COOK-2126] - Add checksum attribute to `windows_zipfile`
* [COOK-2142] - Add printer and `printer_port` LWRPs
* [COOK-2149] - Chef::Log.debug Windows Package command line
* [COOK-2155] -`windows_package` does not send checksum to
`cached_file` in `installer_type`
v1.7.0
------
* [COOK-1745] - allow for newer versions of rubyzip
v1.6.0
------
* [COOK-2048] - undefined method for Falseclass on task :change when
action is :nothing (and task doesn't exist)
* [COOK-2049] - Add `windows_pagefile` resource
v1.5.0
------
* [COOK-1251] - Fix LWRP "NotImplementedError"
* [COOK-1921] - Task LWRP will return true for resource exists when no
other scheduled tasks exist
* [COOK-1932] - Include :change functionality to windows task lwrp
v1.4.0:
------
* [COOK-1571] - `windows_package` resource (with msi provider) does not
accept spaces in filename
* [COOK-1581] - Windows cookbook needs a scheduled tasks LWRP
* [COOK-1584] - `windows_registry` should support all registry types
v1.3.4
------
* [COOK-1173] - `windows_registry` throws Win32::Registry::Error for
action :remove on a nonexistent key
* [COOK-1182] - windows package sets start window title instead of
quoting a path
* [COOK-1476] - zipfile lwrp should support :zip action
* [COOK-1485] - package resource fails to perform install correctly
when "source" contains quote
* [COOK-1519] - add action :remove for path lwrp
v1.3.2
------
* [COOK-1033] - remove the `libraries/ruby_19_patches.rb` file which
causes havoc on non-Windows systems.
* [COOK-811] - add a timeout parameter attribute for `windows_package`
v1.3.0
------
* [COOK-1323] - Update for changes in Chef 0.10.10.
- Setting file mode doesn't make sense on Windows (package provider
- and `reboot_handler` recipe)
- Prefix ::Win32 to avoid namespace collision with Chef::Win32
- (`registry_helper` library)
- Use chef_gem instead of gem_package so gems get installed correctly
under the Ruby environment Chef runs in (reboot_handler recipe,
zipfile provider)
v1.2.12
-------
* [COOK-1037] - specify version for rubyzip gem
* [COOK-1007] - `windows_feature` does not work to remove features with
dism
* [COOK-667] - shortcut resource + provider for Windows platforms
v1.2.10
-------
* [COOK-939] - add `type` parameter to `windows_registry` to allow binary registry keys.
* [COOK-940] - refactor logic so multiple values get created.
v1.2.8
------
* FIX: Older Windows (Windows Server 2003) sometimes return 127 on successful forked commands
* FIX: `windows_package`, ensure we pass the WOW* registry redirection flags into reg.open
v1.2.6
------
* patch to fix [CHEF-2684], Open4 is named Open3 in Ruby 1.9
* Ruby 1.9's Open3 returns 0 and 42 for successful commands
* retry keyword can only be used in a rescue block in Ruby 1.9
v1.2.4
------
* `windows_package` - catch Win32::Registry::Error that pops up when searching certain keys
v1.2.2
------
* combined numerous helper libarires for easier sharing across libaries/LWRPs
* renamed Chef::Provider::WindowsFeature::Base file to the more descriptive `feature_base.rb`
* refactored `windows_path` LWRP
* :add action should MODIFY the the underlying ENV variable (vs CREATE)
* deleted greedy :remove action until it could be made more idempotent
* added a `windows_batch` resource/provider for running batch scripts remotely
v1.2.0
------
* [COOK-745] gracefully handle required server restarts on Windows platform
* WindowsRebootHandler for requested and pending reboots
* `windows_reboot` LWRP for requesting (receiving notifies) reboots
* `reboot_handler` recipe for enabling WindowsRebootHandler as a report handler
* [COOK-714] Correct initialize misspelling
* RegistryHelper - new `get_values` method which returns all values for a particular key.
v1.0.8
------
* [COOK-719] resource/provider for managing windows features
* [COOK-717] remove `windows_env_vars` resource as env resource exists in core chef
* new `Windows::Version` helper class
* refactored `Windows::Helper` mixin
v1.0.6
------
* added `force_modify` action to `windows_registry` resource
* add `win_friendly_path` helper
* re-purpose default recipe to install useful supporting windows related gems
v1.0.4
------
* [COOK-700] new resources and improvements to the `windows_registry` provider (thanks Paul Morton!)
* Open the registry in the bitednes of the OS
* Provide convenience methods to check if keys and values exit
* Provide convenience method for reading registry values
* NEW - `windows_auto_run` resource/provider
* NEW - `windows_env_vars` resource/provider
* NEW - `windows_path` resource/provider
* re-write of the `windows_package` logic for determining current installed packages
* new checksum attribute for `windows_package` resource...useful for remote packages
v1.0.2
------
* [COOK-647] account for Wow6432Node registry redirecter
* [COOK-656] begin/rescue on win32/registry
v1.0.0
------
* [COOK-612] initial release

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,24 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Attribute:: default
#
# Copyright 2011, Chef Software, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
default['windows']['allow_pending_reboots'] = true
default['windows']['allow_reboot_on_failure'] = false
default['windows']['rubyzipversion'] = nil
default['windows']['reboot_timeout'] = 60
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Attribute:: default
#
# Copyright 2011-2015, Chef Software, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
default['windows']['allow_pending_reboots'] = true
default['windows']['allow_reboot_on_failure'] = false
default['windows']['rubyzipversion'] = nil
default['windows']['reboot_timeout'] = 60

View File

@@ -1,76 +1,83 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class WindowsRebootHandler < Chef::Handler
include Chef::Mixin::ShellOut
def initialize(allow_pending_reboots = true, timeout = 60, reason = "Chef Software Chef initiated reboot")
@allow_pending_reboots = allow_pending_reboots
@timeout = timeout
@reason = reason
end
def report
log_message, reboot = begin
if reboot_requested?
["chef_handler[#{self.class}] requested reboot will occur in #{timeout} seconds", true]
elsif reboot_pending?
if @allow_pending_reboots
["chef_handler[#{self.class}] reboot pending - automatic reboot will occur in #{timeout} seconds", true]
else
["chef_handler[#{self.class}] reboot pending but handler not configured to act on pending reboots - please reboot node manually", false]
end
else
["chef_handler[#{self.class}] no reboot requested or pending", false]
end
end
Chef::Log.warn(log_message)
shell_out!("shutdown /r /t #{timeout} /c \"#{reason}\"") if reboot
end
private
# reboot cause CHEF says so:
# reboot explicitly requested in our cookbook code
def reboot_requested?
node.run_state[:reboot_requested] == true
end
# reboot cause WIN says so:
# reboot pending because of some configuration action we performed
def reboot_pending?
# Any files listed here means reboot needed
(Registry.key_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations') &&
Registry.get_value('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager','PendingFileRenameOperations').any?) ||
# 1 for any value means reboot pending
# "9306cdfc-c4a1-4a22-9996-848cb67eddc3"=1
(Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') &&
Registry.get_values('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired').select{|v| v[2] == 1 }.any?) ||
# 1 or 2 for 'Flags' value means reboot pending
(Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') &&
[1,2].include?(Registry::get_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile','Flags')))
end
def timeout
node.run_state[:reboot_timeout] || node['windows']['reboot_timeout'] || @timeout
end
def reason
node.run_state[:reboot_reason] || @reason
end
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class WindowsRebootHandler < Chef::Handler
include Chef::Mixin::ShellOut
def initialize(allow_pending_reboots = true, timeout = 60, reason = 'Chef client run')
@allow_pending_reboots = allow_pending_reboots
@timeout = timeout
@reason = reason
end
def report
log_message, reboot = begin
if reboot_requested?
["chef_handler[#{self.class}] requested reboot will occur in #{timeout} seconds", true]
elsif reboot_pending?
if @allow_pending_reboots
["chef_handler[#{self.class}] reboot pending - automatic reboot will occur in #{timeout} seconds", true]
else
["chef_handler[#{self.class}] reboot pending but handler not configured to act on pending reboots - please reboot node manually", false]
end
else
["chef_handler[#{self.class}] no reboot requested or pending", false]
end
end
Chef::Log.warn(log_message)
shell_out!("shutdown /r /t #{timeout} /c \"#{reason}\"") if reboot
end
private
# reboot cause CHEF says so:
# reboot explicitly requested in our cookbook code
def reboot_requested?
node.run_state[:reboot_requested] == true
end
if Chef::VERSION > '11.12'
include Chef::DSL::RebootPending
else
# reboot cause WIN says so:
# reboot pending because of some configuration action we performed
def reboot_pending?
# this key will only exit if the system need a reboot to update some file currently in use
# see http://technet.microsoft.com/en-us/library/cc960241.aspx
Registry.value_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', 'PendingFileRenameOperations') ||
# 1 for any value means reboot pending
# "9306cdfc-c4a1-4a22-9996-848cb67eddc3"=1
(Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') &&
Registry.get_values('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired').select { |v| v[2] == 1 }.any?) ||
# this key will only exit if the system is pending a reboot
::Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending') ||
# 1, 2 or 3 for 'Flags' value means reboot pending
(Registry.key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') &&
[1, 2, 3].include?(Registry.get_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', 'Flags')))
end
end
def timeout
node.run_state[:reboot_timeout] || node['windows']['reboot_timeout'] || @timeout
end
def reason
node.run_state[:reboot_reason] || @reason
end
end

View File

@@ -1,59 +1,57 @@
class Chef
class Provider
class WindowsFeature
module Base
def action_install
unless installed?
install_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} installed feature")
else
Chef::Log.debug("#{@new_resource} is already installed - nothing to do")
end
end
def action_remove
if installed?
remove_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} removed")
else
Chef::Log.debug("#{@new_resource} feature does not exist - nothing to do")
end
end
def action_delete
if available?
delete_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} deleted")
else
Chef::Log.debug("#{@new_resource} feature is not installed - nothing to do")
end
end
def install_feature(name)
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install"
end
def remove_feature(name)
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remove"
end
def delete_feature(name)
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :delete"
end
def installed?
raise Chef::Exceptions::Override, "You must override installed? in #{self.to_s}"
end
def available?
raise Chef::Exceptions::Override, "You must override available? in #{self.to_s}"
end
end
end
end
end
class Chef
class Provider
class WindowsFeature
module Base
def action_install
unless installed?
install_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} installed feature")
else
Chef::Log.debug("#{@new_resource} is already installed - nothing to do")
end
end
def action_remove
if installed?
remove_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} removed")
else
Chef::Log.debug("#{@new_resource} feature does not exist - nothing to do")
end
end
def action_delete
if available?
delete_feature(@new_resource.feature_name)
@new_resource.updated_by_last_action(true)
Chef::Log.info("#{@new_resource} deleted")
else
Chef::Log.debug("#{@new_resource} feature is not installed - nothing to do")
end
end
def install_feature(_name)
fail Chef::Exceptions::UnsupportedAction, "#{self} does not support :install"
end
def remove_feature(_name)
fail Chef::Exceptions::UnsupportedAction, "#{self} does not support :remove"
end
def delete_feature(_name)
fail Chef::Exceptions::UnsupportedAction, "#{self} does not support :delete"
end
def installed?
fail Chef::Exceptions::Override, "You must override installed? in #{self}"
end
def available?
fail Chef::Exceptions::Override, "You must override available? in #{self}"
end
end
end
end
end

View File

@@ -1,465 +1,452 @@
if defined?(ChefSpec)
chefspec_version = Gem.loaded_specs["chefspec"].version
if chefspec_version < Gem::Version.new('4.1.0')
define_method = ChefSpec::Runner.method(:define_runner_method)
else
define_method = ChefSpec.method(:define_matcher)
end
define_method.call :windows_package
define_method.call :windows_feature
define_method.call :windows_task
define_method.call :windows_path
define_method.call :windows_batch
define_method.call :windows_pagefile
define_method.call :windows_zipfile
define_method.call :windows_shortcut
define_method.call :windows_auto_run
define_method.call :windows_printer
define_method.call :windows_printer_port
define_method.call :windows_reboot
#
# Assert that a +windows_package+ resource exists in the Chef run with the
# action +:install+. Given a Chef Recipe that installs "Node.js" as a
# +windows_package+:
#
# windows_package 'Node.js' do
# source 'http://nodejs.org/dist/v0.10.26/x64/node-v0.10.26-x64.msi'
# action :install
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_package+ resource with ChefSpec.
#
# @example Assert that a +windows_package+ was installed
# expect(chef_run).to install_windows_package('Node.js')
#
# @example Assert that a +windows_package+ was _not_ installed
# expect(chef_run).to_not install_windows_package('7-zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def install_windows_package(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_package, :install, resource_name)
end
#
# Assert that a +windows_package+ resource exists in the Chef run with the
# action +:remove+. Given a Chef Recipe that removes "Node.js" as a
# +windows_package+:
#
# windows_package 'Node.js' do
# action :remove
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_package+ resource with ChefSpec.
#
# @example Assert that a +windows_package+ was installed
# expect(chef_run).to remove_windows_package('Node.js')
#
# @example Assert that a +windows_package+ was _not_ removed
# expect(chef_run).to_not remove_windows_package('7-zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def remove_windows_package(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_package, :remove, resource_name)
end
#
# Assert that a +windows_feature+ resource exists in the Chef run with the
# action +:install+. Given a Chef Recipe that installs "NetFX3" as a
# +windows_feature+:
#
# windows_feature 'NetFX3' do
# action :install
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_feature+ resource with ChefSpec.
#
# @example Assert that a +windows_feature+ was installed
# expect(chef_run).to install_windows_feature('NetFX3')
#
# @example Assert that a +windows_feature+ was _not_ installed
# expect(chef_run).to_not install_windows_feature('NetFX3')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def install_windows_feature(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :install, resource_name)
end
#
# Assert that a +windows_feature+ resource exists in the Chef run with the
# action +:remove+. Given a Chef Recipe that removes "NetFX3" as a
# +windows_feature+:
#
# windows_feature 'NetFX3' do
# action :remove
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_feature+ resource with ChefSpec.
#
# @example Assert that a +windows_feature+ was removed
# expect(chef_run).to remove_windows_feature('NetFX3')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def remove_windows_feature(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :remove, resource_name)
end
#
# Assert that a +windows_feature+ resource exists in the Chef run with the
# action +:delete+. Given a Chef Recipe that deletes "NetFX3" as a
# +windows_feature+:
#
# windows_feature 'NetFX3' do
# action :delete
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_feature+ resource with ChefSpec.
#
# @example Assert that a +windows_feature+ was deleted
# expect(chef_run).to delete_windows_feature('NetFX3')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def delete_windows_feature(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :delete, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:create+. Given a Chef Recipe that creates "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# command 'mybatch.bat'
# action :create
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was created
# expect(chef_run).to create_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def create_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :create, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:delete+. Given a Chef Recipe that deletes "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# action :delete
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was deleted
# expect(chef_run).to delete_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def delete_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :delete, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:run+. Given a Chef Recipe that runs "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# action :run
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was run
# expect(chef_run).to run_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def run_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :run, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:change+. Given a Chef Recipe that changes "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# action :change
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was changed
# expect(chef_run).to change_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def change_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :change, resource_name)
end
#
# Assert that a +windows_path+ resource exists in the Chef run with the
# action +:add+. Given a Chef Recipe that adds "C:\7-Zip" to the Windows
# PATH env var
#
# windows_path 'C:\7-Zip' do
# action :add
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_path+ resource with ChefSpec.
#
# @example Assert that a +windows_path+ was added
# expect(chef_run).to add_windows_path('C:\7-Zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def add_windows_path(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :add, resource_name)
end
#
# Assert that a +windows_path+ resource exists in the Chef run with the
# action +:remove+. Given a Chef Recipe that removes "C:\7-Zip" from the
# Windows PATH env var
#
# windows_path 'C:\7-Zip' do
# action :remove
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_path+ resource with ChefSpec.
#
# @example Assert that a +windows_path+ was removed
# expect(chef_run).to remove_windows_path('C:\7-Zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def remove_windows_path(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :remove, resource_name)
end
#
# Assert that a +windows_batch+ resource exists in the Chef run with the
# action +:run+. Given a Chef Recipe that runs a batch script
#
# windows_batch "unzip_and_move_ruby" do
# code <<-EOH
# 7z.exe x #{Chef::Config[:file_cache_path]}/ruby-1.8.7-p352-i386-mingw32.7z
# -oC:\\source -r -y
# xcopy C:\\source\\ruby-1.8.7-p352-i386-mingw32 C:\\ruby /e /y
# EOH
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_path+ resource with ChefSpec.
#
# @example Assert that a +windows_path+ was removed
# expect(chef_run).to run_windows_batch('unzip_and_move_ruby')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def run_windows_batch(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_batch, :run, resource_name)
end
#
# Assert that a +windows_pagefile+ resource exists in the Chef run with the
# action +:set+. Given a Chef Recipe that sets a pagefile
#
# windows_pagefile "pagefile" do
# system_managed true
# initial_size 1024
# maximum_size 4096
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_pagefile+ resource with ChefSpec.
#
# @example Assert that a +windows_pagefile+ was set
# expect(chef_run).to set_windows_pagefile('pagefile').with(
# initial_size: 1024)
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def set_windows_pagefile(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_pagefile, :set, resource_name)
end
#
# Assert that a +windows_zipfile+ resource exists in the Chef run with the
# action +:unzip+. Given a Chef Recipe that extracts "SysinternalsSuite.zip"
# to c:/bin
#
# windows_zipfile "c:/bin" do
# source "http://download.sysinternals.com/Files/SysinternalsSuite.zip"
# action :unzip
# not_if {::File.exists?("c:/bin/PsExec.exe")}
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_zipfile+ resource with ChefSpec.
#
# @example Assert that a +windows_zipfile+ was unzipped
# expect(chef_run).to unzip_windows_zipfile_to('c:/bin')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def unzip_windows_zipfile_to(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :unzip, resource_name)
end
#
# Assert that a +windows_zipfile+ resource exists in the Chef run with the
# action +:zip+. Given a Chef Recipe that zips "c:/src"
# to c:/code.zip
#
# windows_zipfile "c:/code.zip" do
# source "c:/src"
# action :zip
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_zipfile+ resource with ChefSpec.
#
# @example Assert that a +windows_zipfile+ was zipped
# expect(chef_run).to zip_windows_zipfile_to('c:/code.zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def zip_windows_zipfile_to(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :zip, resource_name)
end
# All the other less commonly used LWRPs
def create_windows_shortcut(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_shortcut, :create, resource_name)
end
def create_windows_auto_run(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :create, resource_name)
end
def remove_windows_auto_run(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :remove, resource_name)
end
def create_windows_printer(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :create, resource_name)
end
def delete_windows_printer(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :delete, resource_name)
end
def create_windows_printer_port(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :create, resource_name)
end
def delete_windows_printer_port(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :delete, resource_name)
end
def request_windows_reboot(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_reboot, :request, resource_name)
end
def cancel_windows_reboot(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_reboot, :cancel, resource_name)
end
end
if defined?(ChefSpec)
chefspec_version = Gem.loaded_specs['chefspec'].version
if chefspec_version < Gem::Version.new('4.1.0')
define_method = ChefSpec::Runner.method(:define_runner_method)
else
define_method = ChefSpec.method(:define_matcher)
end
define_method.call :windows_package
define_method.call :windows_feature
define_method.call :windows_task
define_method.call :windows_path
define_method.call :windows_batch
define_method.call :windows_pagefile
define_method.call :windows_zipfile
define_method.call :windows_shortcut
define_method.call :windows_auto_run
define_method.call :windows_printer
define_method.call :windows_printer_port
define_method.call :windows_reboot
#
# Assert that a +windows_package+ resource exists in the Chef run with the
# action +:install+. Given a Chef Recipe that installs "Node.js" as a
# +windows_package+:
#
# windows_package 'Node.js' do
# source 'http://nodejs.org/dist/v0.10.26/x64/node-v0.10.26-x64.msi'
# action :install
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_package+ resource with ChefSpec.
#
# @example Assert that a +windows_package+ was installed
# expect(chef_run).to install_windows_package('Node.js')
#
# @example Assert that a +windows_package+ was _not_ installed
# expect(chef_run).to_not install_windows_package('7-zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def install_windows_package(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_package, :install, resource_name)
end
#
# Assert that a +windows_package+ resource exists in the Chef run with the
# action +:remove+. Given a Chef Recipe that removes "Node.js" as a
# +windows_package+:
#
# windows_package 'Node.js' do
# action :remove
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_package+ resource with ChefSpec.
#
# @example Assert that a +windows_package+ was installed
# expect(chef_run).to remove_windows_package('Node.js')
#
# @example Assert that a +windows_package+ was _not_ removed
# expect(chef_run).to_not remove_windows_package('7-zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def remove_windows_package(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_package, :remove, resource_name)
end
#
# Assert that a +windows_feature+ resource exists in the Chef run with the
# action +:install+. Given a Chef Recipe that installs "NetFX3" as a
# +windows_feature+:
#
# windows_feature 'NetFX3' do
# action :install
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_feature+ resource with ChefSpec.
#
# @example Assert that a +windows_feature+ was installed
# expect(chef_run).to install_windows_feature('NetFX3')
#
# @example Assert that a +windows_feature+ was _not_ installed
# expect(chef_run).to_not install_windows_feature('NetFX3')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def install_windows_feature(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :install, resource_name)
end
#
# Assert that a +windows_feature+ resource exists in the Chef run with the
# action +:remove+. Given a Chef Recipe that removes "NetFX3" as a
# +windows_feature+:
#
# windows_feature 'NetFX3' do
# action :remove
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_feature+ resource with ChefSpec.
#
# @example Assert that a +windows_feature+ was removed
# expect(chef_run).to remove_windows_feature('NetFX3')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def remove_windows_feature(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :remove, resource_name)
end
#
# Assert that a +windows_feature+ resource exists in the Chef run with the
# action +:delete+. Given a Chef Recipe that deletes "NetFX3" as a
# +windows_feature+:
#
# windows_feature 'NetFX3' do
# action :delete
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_feature+ resource with ChefSpec.
#
# @example Assert that a +windows_feature+ was deleted
# expect(chef_run).to delete_windows_feature('NetFX3')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def delete_windows_feature(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_feature, :delete, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:create+. Given a Chef Recipe that creates "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# command 'mybatch.bat'
# action :create
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was created
# expect(chef_run).to create_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def create_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :create, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:delete+. Given a Chef Recipe that deletes "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# action :delete
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was deleted
# expect(chef_run).to delete_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def delete_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :delete, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:run+. Given a Chef Recipe that runs "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# action :run
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was run
# expect(chef_run).to run_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def run_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :run, resource_name)
end
#
# Assert that a +windows_task+ resource exists in the Chef run with the
# action +:change+. Given a Chef Recipe that changes "mytask" as a
# +windows_task+:
#
# windows_task 'mytask' do
# action :change
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_task+ resource with ChefSpec.
#
# @example Assert that a +windows_task+ was changed
# expect(chef_run).to change_windows_task('mytask')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def change_windows_task(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_task, :change, resource_name)
end
#
# Assert that a +windows_path+ resource exists in the Chef run with the
# action +:add+. Given a Chef Recipe that adds "C:\7-Zip" to the Windows
# PATH env var
#
# windows_path 'C:\7-Zip' do
# action :add
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_path+ resource with ChefSpec.
#
# @example Assert that a +windows_path+ was added
# expect(chef_run).to add_windows_path('C:\7-Zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def add_windows_path(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :add, resource_name)
end
#
# Assert that a +windows_path+ resource exists in the Chef run with the
# action +:remove+. Given a Chef Recipe that removes "C:\7-Zip" from the
# Windows PATH env var
#
# windows_path 'C:\7-Zip' do
# action :remove
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_path+ resource with ChefSpec.
#
# @example Assert that a +windows_path+ was removed
# expect(chef_run).to remove_windows_path('C:\7-Zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def remove_windows_path(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_path, :remove, resource_name)
end
#
# Assert that a +windows_batch+ resource exists in the Chef run with the
# action +:run+. Given a Chef Recipe that runs a batch script
#
# windows_batch "unzip_and_move_ruby" do
# code <<-EOH
# 7z.exe x #{Chef::Config[:file_cache_path]}/ruby-1.8.7-p352-i386-mingw32.7z
# -oC:\\source -r -y
# xcopy C:\\source\\ruby-1.8.7-p352-i386-mingw32 C:\\ruby /e /y
# EOH
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_path+ resource with ChefSpec.
#
# @example Assert that a +windows_path+ was removed
# expect(chef_run).to run_windows_batch('unzip_and_move_ruby')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def run_windows_batch(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_batch, :run, resource_name)
end
#
# Assert that a +windows_pagefile+ resource exists in the Chef run with the
# action +:set+. Given a Chef Recipe that sets a pagefile
#
# windows_pagefile "pagefile" do
# system_managed true
# initial_size 1024
# maximum_size 4096
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_pagefile+ resource with ChefSpec.
#
# @example Assert that a +windows_pagefile+ was set
# expect(chef_run).to set_windows_pagefile('pagefile').with(
# initial_size: 1024)
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def set_windows_pagefile(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_pagefile, :set, resource_name)
end
#
# Assert that a +windows_zipfile+ resource exists in the Chef run with the
# action +:unzip+. Given a Chef Recipe that extracts "SysinternalsSuite.zip"
# to c:/bin
#
# windows_zipfile "c:/bin" do
# source "http://download.sysinternals.com/Files/SysinternalsSuite.zip"
# action :unzip
# not_if {::File.exists?("c:/bin/PsExec.exe")}
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_zipfile+ resource with ChefSpec.
#
# @example Assert that a +windows_zipfile+ was unzipped
# expect(chef_run).to unzip_windows_zipfile_to('c:/bin')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def unzip_windows_zipfile_to(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :unzip, resource_name)
end
#
# Assert that a +windows_zipfile+ resource exists in the Chef run with the
# action +:zip+. Given a Chef Recipe that zips "c:/src"
# to c:/code.zip
#
# windows_zipfile "c:/code.zip" do
# source "c:/src"
# action :zip
# end
#
# The Examples section demonstrates the different ways to test a
# +windows_zipfile+ resource with ChefSpec.
#
# @example Assert that a +windows_zipfile+ was zipped
# expect(chef_run).to zip_windows_zipfile_to('c:/code.zip')
#
#
# @param [String, Regex] resource_name
# the name of the resource to match
#
# @return [ChefSpec::Matchers::ResourceMatcher]
#
def zip_windows_zipfile_to(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_zipfile, :zip, resource_name)
end
# All the other less commonly used LWRPs
def create_windows_shortcut(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_shortcut, :create, resource_name)
end
def create_windows_auto_run(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :create, resource_name)
end
def remove_windows_auto_run(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_auto_run, :remove, resource_name)
end
def create_windows_printer(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :create, resource_name)
end
def delete_windows_printer(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer, :delete, resource_name)
end
def create_windows_printer_port(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :create, resource_name)
end
def delete_windows_printer_port(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_printer_port, :delete, resource_name)
end
def request_windows_reboot(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_reboot, :request, resource_name)
end
def cancel_windows_reboot(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:windows_reboot, :cancel, resource_name)
end
end

View File

@@ -1,59 +1,53 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Library:: helper
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/mixin/shell_out'
module Powershell
module Helper
include Chef::Mixin::ShellOut
def powershell_installed?
!powershell_version.nil?
end
def interpreter
# force 64-bit powershell from 32-bit ruby process
if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
else
"powershell.exe"
end
end
def powershell_version
begin
cmd = shell_out("#{interpreter} -InputFormat none -Command \"& echo $PSVersionTable.psversion.major\"")
if cmd.stdout.empty? # PowerShell 1.0 doesn't have a $PSVersionTable
1
else
if cmd.stdout =~ /^(\d+)/
$1.to_i
else
nil
end
end
rescue Errno::ENOENT
nil
end
end
end
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Library:: helper
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/mixin/shell_out'
module Powershell
module Helper
include Chef::Mixin::ShellOut
def powershell_installed?
!powershell_version.nil?
end
def interpreter
# force 64-bit powershell from 32-bit ruby process
if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
else
'powershell.exe'
end
end
def powershell_version
cmd = shell_out("#{interpreter} -InputFormat none -Command \"& echo $PSVersionTable.psversion.major\"")
if cmd.stdout.empty? # PowerShell 1.0 doesn't have a $PSVersionTable
1
else
Regexp.last_match(1).to_i if cmd.stdout =~ /^(\d+)/
end
rescue Errno::ENOENT
nil
end
end
end

View File

@@ -1,79 +1,92 @@
class Chef
module Mixin
module PowershellOut
include Chef::Mixin::ShellOut
begin
include Chef::Mixin::WindowsArchitectureHelper
rescue
# nothing to do, as the include will happen when windows_architecture_helper.rb
# is loaded. This is for ease of removal of that library when either
# powershell_out is core chef or powershell cookbook depends upon version
# of chef that has Chef::Mixin::WindowsArchitectureHelper in core chef
end
def powershell_out(*command_args)
script = command_args.first
options = command_args.last.is_a?(Hash) ? command_args.last : nil
run_command(script, options)
end
def powershell_out!(*command_args)
cmd = powershell_out(*command_args)
cmd.error!
cmd
end
private
def run_command(script, options)
if options && options[:architecture]
architecture = options[:architecture]
options.delete(:architecture)
else
architecture = node_windows_architecture(node)
end
disable_redirection = wow64_architecture_override_required?(node, architecture)
if disable_redirection
original_redirection_state = disable_wow64_file_redirection(node)
end
command = build_command(script)
if options
cmd = shell_out(command, options)
else
cmd = shell_out(command)
end
if disable_redirection
restore_wow64_file_redirection(node, original_redirection_state)
end
cmd
end
def build_command(script)
flags = [
# Hides the copyright banner at startup.
"-NoLogo",
# Does not present an interactive prompt to the user.
"-NonInteractive",
# Does not load the Windows PowerShell profile.
"-NoProfile",
# always set the ExecutionPolicy flag
# see http://technet.microsoft.com/en-us/library/ee176961.aspx
"-ExecutionPolicy RemoteSigned",
# Powershell will hang if STDIN is redirected
# http://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected
"-InputFormat None"
]
command = "powershell.exe #{flags.join(' ')} -Command \"#{script}\""
command
end
end
end
end
#
# WARNING
#
# THIS CODE HAS BEEN MOVED TO CORE CHEF. DO NOT SUMBIT PULL REQUESTS AGAINST THIS
# CODE. IT WILL BE REMOVED IN THE FUTURE.
#
unless defined? Chef::Mixin::PowershellOut
class Chef
module Mixin
module PowershellOut
include Chef::Mixin::ShellOut
begin
include Chef::Mixin::WindowsArchitectureHelper
rescue
# nothing to do, as the include will happen when windows_architecture_helper.rb
# is loaded. This is for ease of removal of that library when either
# powershell_out is core chef or powershell cookbook depends upon version
# of chef that has Chef::Mixin::WindowsArchitectureHelper in core chef
end
def powershell_out(*command_args)
Chef::Log.warn 'The powershell_out library in the windows cookbook is deprecated.'
Chef::Log.warn 'Please upgrade to Chef 12.4.0 or later where it is built-in to core chef.'
script = command_args.first
options = command_args.last.is_a?(Hash) ? command_args.last : nil
run_command(script, options)
end
def powershell_out!(*command_args)
cmd = powershell_out(*command_args)
cmd.error!
cmd
end
private
def run_command(script, options)
if options && options[:architecture]
architecture = options[:architecture]
options.delete(:architecture)
else
architecture = node_windows_architecture(node)
end
disable_redirection = wow64_architecture_override_required?(node, architecture)
if disable_redirection
original_redirection_state = disable_wow64_file_redirection(node)
end
command = build_command(script)
if options
cmd = shell_out(command, options)
else
cmd = shell_out(command)
end
if disable_redirection
restore_wow64_file_redirection(node, original_redirection_state)
end
cmd
end
def build_command(script)
flags = [
# Hides the copyright banner at startup.
'-NoLogo',
# Does not present an interactive prompt to the user.
'-NonInteractive',
# Does not load the Windows PowerShell profile.
'-NoProfile',
# always set the ExecutionPolicy flag
# see http://technet.microsoft.com/en-us/library/ee176961.aspx
'-ExecutionPolicy RemoteSigned',
# Powershell will hang if STDIN is redirected
# http://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected
'-InputFormat None'
]
command = "powershell.exe #{flags.join(' ')} -Command \"#{script}\""
command
end
end
end
end
end

View File

@@ -1,364 +1,355 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Chef Software, Inc.
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'win32/registry'
require_relative 'wmi_helper'
end
module Windows
module RegistryHelper
@@native_registry_constant = ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64' ? 0x0100 : 0x0200
def get_hive_name(path)
Chef::Log.debug("Resolving registry shortcuts to full names")
reg_path = path.split("\\")
hive_name = reg_path.shift
hkey = {
"HKLM" => "HKEY_LOCAL_MACHINE",
"HKCU" => "HKEY_CURRENT_USER",
"HKU" => "HKEY_USERS"
}[hive_name] || hive_name
Chef::Log.debug("Hive resolved to #{hkey}")
return hkey
end
def get_hive(path)
Chef::Log.debug("Getting hive for #{path}")
reg_path = path.split("\\")
hive_name = reg_path.shift
hkey = get_hive_name(path)
hive = {
"HKEY_LOCAL_MACHINE" => ::Win32::Registry::HKEY_LOCAL_MACHINE,
"HKEY_USERS" => ::Win32::Registry::HKEY_USERS,
"HKEY_CURRENT_USER" => ::Win32::Registry::HKEY_CURRENT_USER
}[hkey]
unless hive
Chef::Application.fatal!("Unsupported registry hive '#{hive_name}'")
end
Chef::Log.debug("Registry hive resolved to #{hkey}")
return hive
end
def unload_hive(path)
hive = get_hive(path)
if hive == ::Win32::Registry::HKEY_USERS
reg_path = path.split("\\")
priv = Chef::WindowsPrivileged.new
begin
priv.reg_unload_key(reg_path[1])
rescue
end
end
end
def set_value(mode,path,values,type=nil)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key_name = reg_path.join("\\")
Chef::Log.debug("Creating #{path}")
if !key_exists?(path,true)
create_key(path)
end
hive.send(mode, key_name, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg|
changed_something = false
values.each do |k,val|
key = k.to_s #wtf. avoid "can't modify frozen string" in win32/registry.rb
cur_val = nil
begin
cur_val = reg[key]
rescue
#subkey does not exist (ok)
end
if cur_val != val
Chef::Log.debug("setting #{key}=#{val}")
if type.nil?
type = :string
end
reg_type = {
:binary => ::Win32::Registry::REG_BINARY,
:string => ::Win32::Registry::REG_SZ,
:multi_string => ::Win32::Registry::REG_MULTI_SZ,
:expand_string => ::Win32::Registry::REG_EXPAND_SZ,
:dword => ::Win32::Registry::REG_DWORD,
:dword_big_endian => ::Win32::Registry::REG_DWORD_BIG_ENDIAN,
:qword => ::Win32::Registry::REG_QWORD
}[type]
reg.write(key, reg_type, val)
ensure_hive_unloaded(hive_loaded)
changed_something = true
end
end
return changed_something
end
return false
end
def get_value(path,value)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do | reg |
begin
return reg[value]
rescue
return nil
ensure
ensure_hive_unloaded(hive_loaded)
end
end
end
def get_values(path)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do | reg |
values = []
begin
reg.each_value do |name, type, data|
values << [name, type, data]
end
rescue
ensure
ensure_hive_unloaded(hive_loaded)
end
values
end
end
def delete_value(path,values)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
Chef::Log.debug("Deleting values in #{path}")
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do | reg |
values.each_key { |key|
name = key.to_s
# Ensure delete operation is idempotent.
if value_exists?(path, key)
Chef::Log.debug("Deleting value #{name} in #{path}")
reg.delete_value(name)
else
Chef::Log.debug("Value #{name} in #{path} does not exist, skipping.")
end
}
end
end
def create_key(path)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
Chef::Log.debug("Creating registry key #{path}")
hive.create(key)
end
def value_exists?(path,value)
if key_exists?(path,true)
hive, reg_path, hive_name, root_key , hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
Chef::Log.debug("Attempting to open #{key}");
Chef::Log.debug("Native Constant #{@@native_registry_constant}")
Chef::Log.debug("Hive #{hive}")
hive.open(key, ::Win32::Registry::KEY_READ | @@native_registry_constant) do | reg |
begin
rtn_value = reg[value]
return true
rescue
return false
ensure
ensure_hive_unloaded(hive_loaded)
end
end
end
return false
end
# TODO: Does not load user registry...
def key_exists?(path, load_hive = false)
if load_hive
hive, reg_path, hive_name, root_key , hive_loaded = get_reg_path_info(path)
key = reg_path.join("\\")
else
hive = get_hive(path)
reg_path = path.split("\\")
hive_name = reg_path.shift
root_key = reg_path[0]
key = reg_path.join("\\")
hive_loaded = false
end
begin
hive.open(key, ::Win32::Registry::Constants::KEY_READ | @@native_registry_constant )
return true
rescue
return false
ensure
ensure_hive_unloaded(hive_loaded)
end
end
def get_user_hive_location(sid)
reg_key = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}"
Chef::Log.debug("Looking for profile at #{reg_key}")
if key_exists?(reg_key)
return get_value(reg_key,'ProfileImagePath')
else
return nil
end
end
def resolve_user_to_sid(username)
begin
user_query = execute_wmi_query("select * from Win32_UserAccount where Name='#{username}'")
sid = nil
user_query.each do |user|
sid = wmi_object_property(user, 'sid')
break
end
Chef::Log.debug("Resolved user SID to #{sid}")
return sid
rescue
return nil
end
end
def hive_loaded?(path)
hive = get_hive(path)
reg_path = path.split("\\")
hive_name = reg_path.shift
user_hive = path[0]
if is_user_hive?(hive)
return key_exists?("#{hive_name}\\#{user_hive}")
else
return true
end
end
def is_user_hive?(hive)
if hive == ::Win32::Registry::HKEY_USERS
return true
else
return true
end
end
def get_reg_path_info(path)
hive = get_hive(path)
reg_path = path.split("\\")
hive_name = reg_path.shift
root_key = reg_path[0]
hive_loaded = false
if is_user_hive?(hive) && !key_exists?("#{hive_name}\\#{root_key}")
reg_path, hive_loaded = load_user_hive(hive,reg_path,root_key)
root_key = reg_path[0]
Chef::Log.debug("Resolved user (#{path}) to (#{reg_path.join('/')})")
end
return hive, reg_path, hive_name, root_key, hive_loaded
end
def load_user_hive(hive,reg_path,user_hive)
Chef::Log.debug("Reg Path #{reg_path}")
# See if the hive is loaded. Logged in users will have a key that is named their SID
# if the user has specified the a path by SID and the user is logged in, this function
# should not be executed.
if is_user_hive?(hive) && !key_exists?("HKU\\#{user_hive}")
Chef::Log.debug("The user is not logged in and has not been specified by SID")
sid = resolve_user_to_sid(user_hive)
Chef::Log.debug("User SID resolved to (#{sid})")
# Now that the user has been resolved to a SID, check and see if the hive exists.
# If this exists by SID, the user is logged in and we should use that key.
# TODO: Replace the username with the sid and send it back because the username
# does not exist as the key location.
load_reg = false
if key_exists?("HKU\\#{sid}")
reg_path[0] = sid #use the active profile (user is logged on)
Chef::Log.debug("HKEY_USERS Mapped: #{user_hive} -> #{sid}")
else
Chef::Log.debug("User is not logged in")
load_reg = true
end
# The user is not logged in, so we should load the registry from disk
if load_reg
profile_path = get_user_hive_location(sid)
if profile_path != nil
ntuser_dat = "#{profile_path}\\NTUSER.DAT"
if ::File.exists?(ntuser_dat)
priv = Chef::WindowsPrivileged.new
if priv.reg_load_key(sid,ntuser_dat)
Chef::Log.debug("RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})")
reg_path[0] = sid
else
Chef::Log.debug("Failed RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})")
end
end
end
end
end
return reg_path, load_reg
end
private
def ensure_hive_unloaded(hive_loaded=false)
if(hive_loaded)
Chef::Log.debug("Hive was loaded, we really should unload it")
unload_hive(path)
end
end
end
end
module Registry
module_function
extend Windows::RegistryHelper
end
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011-2015, Chef Software, Inc.
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'win32/registry'
require_relative 'wmi_helper'
end
module Windows
module RegistryHelper
@@native_registry_constant = ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64' ? 0x0100 : 0x0200
def get_hive_name(path)
Chef::Log.debug('Resolving registry shortcuts to full names')
reg_path = path.split('\\')
hive_name = reg_path.shift
hkey = {
'HKLM' => 'HKEY_LOCAL_MACHINE',
'HKCU' => 'HKEY_CURRENT_USER',
'HKU' => 'HKEY_USERS'
}[hive_name] || hive_name
Chef::Log.debug("Hive resolved to #{hkey}")
hkey
end
def get_hive(path)
Chef::Log.debug("Getting hive for #{path}")
reg_path = path.split('\\')
hive_name = reg_path.shift
hkey = get_hive_name(path)
hive = {
'HKEY_LOCAL_MACHINE' => ::Win32::Registry::HKEY_LOCAL_MACHINE,
'HKEY_USERS' => ::Win32::Registry::HKEY_USERS,
'HKEY_CURRENT_USER' => ::Win32::Registry::HKEY_CURRENT_USER
}[hkey]
unless hive
Chef::Application.fatal!("Unsupported registry hive '#{hive_name}'")
end
Chef::Log.debug("Registry hive resolved to #{hkey}")
hive
end
def unload_hive(path)
hive = get_hive(path)
if hive == ::Win32::Registry::HKEY_USERS
reg_path = path.split('\\')
priv = Chef::WindowsPrivileged.new
begin
priv.reg_unload_key(reg_path[1])
rescue
end
end
end
def set_value(mode, path, values, type = nil)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key_name = reg_path.join('\\')
Chef::Log.debug("Creating #{path}")
create_key(path) unless key_exists?(path, true)
hive.send(mode, key_name, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg|
changed_something = false
values.each do |k, val|
key = k.to_s # wtf. avoid "can't modify frozen string" in win32/registry.rb
cur_val = nil
begin
cur_val = reg[key]
rescue
# subkey does not exist (ok)
end
next unless cur_val != val
Chef::Log.debug("setting #{key}=#{val}")
type = :string if type.nil?
reg_type = {
binary: ::Win32::Registry::REG_BINARY,
string: ::Win32::Registry::REG_SZ,
multi_string: ::Win32::Registry::REG_MULTI_SZ,
expand_string: ::Win32::Registry::REG_EXPAND_SZ,
dword: ::Win32::Registry::REG_DWORD,
dword_big_endian: ::Win32::Registry::REG_DWORD_BIG_ENDIAN,
qword: ::Win32::Registry::REG_QWORD
}[type]
reg.write(key, reg_type, val)
ensure_hive_unloaded(hive_loaded)
changed_something = true
end
return changed_something
end
false
end
def get_value(path, value)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join('\\')
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg|
begin
return reg[value]
rescue
return nil
ensure
ensure_hive_unloaded(hive_loaded)
end
end
end
def get_values(path)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join('\\')
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg|
values = []
begin
reg.each_value do |name, type, data|
values << [name, type, data]
end
rescue
ensure
ensure_hive_unloaded(hive_loaded)
end
values
end
end
def delete_value(path, values)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join('\\')
Chef::Log.debug("Deleting values in #{path}")
hive.open(key, ::Win32::Registry::KEY_ALL_ACCESS | @@native_registry_constant) do |reg|
values.each_key do |key|
name = key.to_s
# Ensure delete operation is idempotent.
if value_exists?(path, key)
Chef::Log.debug("Deleting value #{name} in #{path}")
reg.delete_value(name)
else
Chef::Log.debug("Value #{name} in #{path} does not exist, skipping.")
end
end
end
end
def create_key(path)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join('\\')
Chef::Log.debug("Creating registry key #{path}")
hive.create(key)
end
def value_exists?(path, value)
if key_exists?(path, true)
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join('\\')
Chef::Log.debug("Attempting to open #{key}")
Chef::Log.debug("Native Constant #{@@native_registry_constant}")
Chef::Log.debug("Hive #{hive}")
hive.open(key, ::Win32::Registry::KEY_READ | @@native_registry_constant) do |reg|
begin
rtn_value = reg[value]
return true
rescue
return false
ensure
ensure_hive_unloaded(hive_loaded)
end
end
end
false
end
# TODO: Does not load user registry...
def key_exists?(path, load_hive = false)
if load_hive
hive, reg_path, hive_name, root_key, hive_loaded = get_reg_path_info(path)
key = reg_path.join('\\')
else
hive = get_hive(path)
reg_path = path.split('\\')
hive_name = reg_path.shift
root_key = reg_path[0]
key = reg_path.join('\\')
hive_loaded = false
end
begin
hive.open(key, ::Win32::Registry::Constants::KEY_READ | @@native_registry_constant)
return true
rescue
return false
ensure
ensure_hive_unloaded(hive_loaded)
end
end
def get_user_hive_location(sid)
reg_key = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}"
Chef::Log.debug("Looking for profile at #{reg_key}")
if key_exists?(reg_key)
return get_value(reg_key, 'ProfileImagePath')
else
return nil
end
end
def resolve_user_to_sid(username)
user_query = execute_wmi_query("select * from Win32_UserAccount where Name='#{username}'")
sid = nil
user_query.each do |user|
sid = wmi_object_property(user, 'sid')
break
end
Chef::Log.debug("Resolved user SID to #{sid}")
return sid
rescue
return nil
end
def hive_loaded?(path)
hive = get_hive(path)
reg_path = path.split('\\')
hive_name = reg_path.shift
user_hive = path[0]
if user_hive?(hive)
return key_exists?("#{hive_name}\\#{user_hive}")
else
return true
end
end
def user_hive?(hive)
if hive == ::Win32::Registry::HKEY_USERS
return true
else
return true
end
end
def get_reg_path_info(path)
hive = get_hive(path)
reg_path = path.split('\\')
hive_name = reg_path.shift
root_key = reg_path[0]
hive_loaded = false
if user_hive?(hive) && !key_exists?("#{hive_name}\\#{root_key}")
reg_path, hive_loaded = load_user_hive(hive, reg_path, root_key)
root_key = reg_path[0]
Chef::Log.debug("Resolved user (#{path}) to (#{reg_path.join('/')})")
end
[hive, reg_path, hive_name, root_key, hive_loaded]
end
def load_user_hive(hive, reg_path, user_hive)
Chef::Log.debug("Reg Path #{reg_path}")
# See if the hive is loaded. Logged in users will have a key that is named their SID
# if the user has specified the a path by SID and the user is logged in, this function
# should not be executed.
if user_hive?(hive) && !key_exists?("HKU\\#{user_hive}")
Chef::Log.debug('The user is not logged in and has not been specified by SID')
sid = resolve_user_to_sid(user_hive)
Chef::Log.debug("User SID resolved to (#{sid})")
# Now that the user has been resolved to a SID, check and see if the hive exists.
# If this exists by SID, the user is logged in and we should use that key.
# TODO: Replace the username with the sid and send it back because the username
# does not exist as the key location.
load_reg = false
if key_exists?("HKU\\#{sid}")
reg_path[0] = sid # use the active profile (user is logged on)
Chef::Log.debug("HKEY_USERS Mapped: #{user_hive} -> #{sid}")
else
Chef::Log.debug('User is not logged in')
load_reg = true
end
# The user is not logged in, so we should load the registry from disk
if load_reg
profile_path = get_user_hive_location(sid)
unless profile_path.nil?
ntuser_dat = "#{profile_path}\\NTUSER.DAT"
if ::File.exist?(ntuser_dat)
priv = Chef::WindowsPrivileged.new
if priv.reg_load_key(sid, ntuser_dat)
Chef::Log.debug("RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})")
reg_path[0] = sid
else
Chef::Log.debug("Failed RegLoadKey(#{sid}, #{user_hive}, #{ntuser_dat})")
end
end
end
end
end
[reg_path, load_reg]
end
private
def ensure_hive_unloaded(hive_loaded = false)
if hive_loaded
Chef::Log.debug('Hive was loaded, we really should unload it')
unload_hive(path)
end
end
end
end
module Registry
module_function
extend Windows::RegistryHelper
end

View File

@@ -1,207 +1,207 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Library:: version
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require_relative 'wmi_helper'
require 'Win32API'
end
module Windows
class Version
# http://msdn.microsoft.com/en-us/library/ms724833(v=vs.85).aspx
# Suite Masks
# Microsoft BackOffice components are installed.
VER_SUITE_BACKOFFICE = 0x00000004.freeze unless defined?(VER_SUITE_BACKOFFICE)
# Windows Server 2003, Web Edition is installed.
VER_SUITE_BLADE = 0x00000400.freeze unless defined?(VER_SUITE_BLADE)
# Windows Server 2003, Compute Cluster Edition is installed.
VER_SUITE_COMPUTE_SERVER = 0x00004000.freeze unless defined?(VER_SUITE_COMPUTE_SERVER)
# Windows Server 2008 Datacenter, Windows Server 2003, Datacenter Edition, or Windows 2000 Datacenter Server is installed.
VER_SUITE_DATACENTER = 0x00000080.freeze unless defined?(VER_SUITE_DATACENTER)
# Windows Server 2008 Enterprise, Windows Server 2003, Enterprise Edition, or Windows 2000 Advanced Server is installed. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_ENTERPRISE = 0x00000002.freeze unless defined?(VER_SUITE_ENTERPRISE)
# Windows XP Embedded is installed.
VER_SUITE_EMBEDDEDNT = 0x00000040.freeze unless defined?(VER_SUITE_EMBEDDEDNT)
# Windows Vista Home Premium, Windows Vista Home Basic, or Windows XP Home Edition is installed.
VER_SUITE_PERSONAL = 0x00000200.freeze unless defined?(VER_SUITE_PERSONAL)
# Remote Desktop is supported, but only one interactive session is supported. This value is set unless the system is running in application server mode.
VER_SUITE_SINGLEUSERTS = 0x00000100.freeze unless defined?(VER_SUITE_SINGLEUSERTS)
# Microsoft Small Business Server was once installed on the system, but may have been upgraded to another version of Windows. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_SMALLBUSINESS = 0x00000001.freeze unless defined?(VER_SUITE_SMALLBUSINESS)
# Microsoft Small Business Server is installed with the restrictive client license in force. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020.freeze unless defined?(VER_SUITE_SMALLBUSINESS_RESTRICTED)
# Windows Storage Server 2003 R2 or Windows Storage Server 2003is installed.
VER_SUITE_STORAGE_SERVER = 0x00002000.freeze unless defined?(VER_SUITE_STORAGE_SERVER)
# Terminal Services is installed. This value is always set.
# If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, the system is running in application server mode.
VER_SUITE_TERMINAL = 0x00000010.freeze unless defined?(VER_SUITE_TERMINAL)
# Windows Home Server is installed.
VER_SUITE_WH_SERVER = 0x00008000.freeze unless defined?(VER_SUITE_WH_SERVER)
# Product Type
# The system is a domain controller and the operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
VER_NT_DOMAIN_CONTROLLER = 0x0000002.freeze unless defined?(VER_NT_DOMAIN_CONTROLLER)
# The operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
# Note that a server that is also a domain controller is reported as VER_NT_DOMAIN_CONTROLLER, not VER_NT_SERVER.
VER_NT_SERVER = 0x0000003.freeze unless defined?(VER_NT_SERVER)
# The operating system is Windows 7, Windows Vista, Windows XP Professional, Windows XP Home Edition, or Windows 2000 Professional.
VER_NT_WORKSTATION = 0x0000001.freeze unless defined?(VER_NT_WORKSTATION)
# GetSystemMetrics
# The build number if the system is Windows Server 2003 R2; otherwise, 0.
SM_SERVERR2 = 89.freeze unless defined?(SM_SERVERR2)
# http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx
SKU = {
0x00000006 => {:ms_const => 'PRODUCT_BUSINESS', :name => 'Business'},
0x00000010 => {:ms_const => 'PRODUCT_BUSINESS_N', :name => 'Business N'},
0x00000012 => {:ms_const => 'PRODUCT_CLUSTER_SERVER', :name => 'HPC Edition'},
0x00000008 => {:ms_const => 'PRODUCT_DATACENTER_SERVER', :name => 'Server Datacenter (full installation)'},
0x0000000C => {:ms_const => 'PRODUCT_DATACENTER_SERVER_CORE', :name => 'Server Datacenter (core installation)'},
0x00000027 => {:ms_const => 'PRODUCT_DATACENTER_SERVER_CORE_V', :name => 'Server Datacenter without Hyper-V (core installation)'},
0x00000025 => {:ms_const => 'PRODUCT_DATACENTER_SERVER_V', :name => 'Server Datacenter without Hyper-V (full installation)'},
0x00000004 => {:ms_const => 'PRODUCT_ENTERPRISE', :name => 'Enterprise'},
0x00000046 => {:ms_const => 'PRODUCT_ENTERPRISE_E', :name => 'Not supported'},
0x0000001B => {:ms_const => 'PRODUCT_ENTERPRISE_N', :name => 'Enterprise N'},
0x0000000A => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER', :name => 'Server Enterprise (full installation)'},
0x0000000E => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_CORE', :name => 'Server Enterprise (core installation)'},
0x00000029 => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_CORE_V', :name => 'Server Enterprise without Hyper-V (core installation)'},
0x0000000F => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_IA64', :name => 'Server Enterprise for Itanium-based Systems'},
0x00000026 => {:ms_const => 'PRODUCT_ENTERPRISE_SERVER_V', :name => 'Server Enterprise without Hyper-V (full installation)'},
0x00000002 => {:ms_const => 'PRODUCT_HOME_BASIC', :name => 'Home Basic'},
0x00000043 => {:ms_const => 'PRODUCT_HOME_BASIC_E', :name => 'Not supported'},
0x00000005 => {:ms_const => 'PRODUCT_HOME_BASIC_N', :name => 'Home Basic N'},
0x00000003 => {:ms_const => 'PRODUCT_HOME_PREMIUM', :name => 'Home Premium'},
0x00000044 => {:ms_const => 'PRODUCT_HOME_PREMIUM_E', :name => 'Not supported'},
0x0000001A => {:ms_const => 'PRODUCT_HOME_PREMIUM_N', :name => 'Home Premium N'},
0x0000002A => {:ms_const => 'PRODUCT_HYPERV', :name => 'Microsoft Hyper-V Server'},
0x0000001E => {:ms_const => 'PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT', :name => 'Windows Essential Business Server Management Server'},
0x00000020 => {:ms_const => 'PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING', :name => 'Windows Essential Business Server Messaging Server'},
0x0000001F => {:ms_const => 'PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY', :name => 'Windows Essential Business Server Security Server'},
0x00000030 => {:ms_const => 'PRODUCT_PROFESSIONAL', :name => 'Professional'},
0x00000045 => {:ms_const => 'PRODUCT_PROFESSIONAL_E', :name => 'Not supported'},
0x00000031 => {:ms_const => 'PRODUCT_PROFESSIONAL_N', :name => 'Professional N'},
0x00000067 => {:ms_const => 'PRODUCT_PROFESSIONAL_WMC', :name => 'Professional with Media Center'},
0x00000018 => {:ms_const => 'PRODUCT_SERVER_FOR_SMALLBUSINESS', :name => 'Windows Server 2008 for Windows Essential Server Solutions'},
0x00000023 => {:ms_const => 'PRODUCT_SERVER_FOR_SMALLBUSINESS_V', :name => 'Windows Server 2008 without Hyper-V for Windows Essential Server Solutions'},
0x00000021 => {:ms_const => 'PRODUCT_SERVER_FOUNDATION', :name => 'Server Foundation'},
0x00000022 => {:ms_const => 'PRODUCT_HOME_PREMIUM_SERVER', :name => 'Windows Home Server 2011'},
0x00000032 => {:ms_const => 'PRODUCT_SB_SOLUTION_SERVER', :name => 'Windows Small Business Server 2011 Essentials'},
0x00000013 => {:ms_const => 'PRODUCT_HOME_SERVER', :name => 'Windows Storage Server 2008 R2 Essentials'},
0x00000009 => {:ms_const => 'PRODUCT_SMALLBUSINESS_SERVER', :name => 'Windows Small Business Server'},
0x00000038 => {:ms_const => 'PRODUCT_SOLUTION_EMBEDDEDSERVER', :name => 'Windows MultiPoint Server'},
0x00000007 => {:ms_const => 'PRODUCT_STANDARD_SERVER', :name => 'Server Standard (full installation)'},
0x0000000D => {:ms_const => 'PRODUCT_STANDARD_SERVER_CORE', :name => 'Server Standard (core installation)'},
0x00000028 => {:ms_const => 'PRODUCT_STANDARD_SERVER_CORE_V', :name => 'Server Standard without Hyper-V (core installation)'},
0x00000024 => {:ms_const => 'PRODUCT_STANDARD_SERVER_V', :name => 'Server Standard without Hyper-V (full installation)'},
0x0000000B => {:ms_const => 'PRODUCT_STARTER', :name => 'Starter'},
0x00000042 => {:ms_const => 'PRODUCT_STARTER_E', :name => 'Not supported'},
0x0000002F => {:ms_const => 'PRODUCT_STARTER_N', :name => 'Starter N'},
0x00000017 => {:ms_const => 'PRODUCT_STORAGE_ENTERPRISE_SERVER', :name => 'Storage Server Enterprise'},
0x00000014 => {:ms_const => 'PRODUCT_STORAGE_EXPRESS_SERVER', :name => 'Storage Server Express'},
0x00000015 => {:ms_const => 'PRODUCT_STORAGE_STANDARD_SERVER', :name => 'Storage Server Standard'},
0x00000016 => {:ms_const => 'PRODUCT_STORAGE_WORKGROUP_SERVER', :name => 'Storage Server Workgroup'},
0x00000000 => {:ms_const => 'PRODUCT_UNDEFINED', :name => 'An unknown product'},
0x00000001 => {:ms_const => 'PRODUCT_ULTIMATE', :name => 'Ultimate'},
0x00000047 => {:ms_const => 'PRODUCT_ULTIMATE_E', :name => 'Not supported'},
0x0000001C => {:ms_const => 'PRODUCT_ULTIMATE_N', :name => 'Ultimate N'},
0x00000011 => {:ms_const => 'PRODUCT_WEB_SERVER', :name => 'Web Server (full installation)'},
0x0000001D => {:ms_const => 'PRODUCT_WEB_SERVER_CORE', :name => 'Web Server (core installation)'}
}.freeze unless defined?(SKU)
attr_reader :major_version, :minor_version, :build_number, :service_pack_major_version, :service_pack_minor_version
attr_reader :version, :product_type, :product_suite, :sku
def initialize
unless RUBY_PLATFORM =~ /mswin|mingw32|windows/
raise NotImplementedError, 'only valid on Windows platform'
end
@version, @product_type, @product_suite, @sku, @service_pack_major_version, @service_pack_minor_version = get_os_info
@major_version, @minor_version, @build_number = version.split('.').map{|v| v.to_i }
end
WIN_VERSIONS = {
"Windows Server 2012 R2" => {:major => 6, :minor => 3, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows 8" => {:major => 6, :minor => 2, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
"Windows Server 2012" => {:major => 6, :minor => 2, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows 7" => {:major => 6, :minor => 1, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
"Windows Server 2008 R2" => {:major => 6, :minor => 1, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows Server 2008" => {:major => 6, :minor => 0, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows Vista" => {:major => 6, :minor => 0, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
"Windows Server 2003 R2" => {:major => 5, :minor => 2, :callable => lambda{ Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) != 0 }},
"Windows Home Server" => {:major => 5, :minor => 2, :callable => lambda{ (@product_suite & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER }},
"Windows Server 2003" => {:major => 5, :minor => 2, :callable => lambda{ Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) == 0 }},
"Windows XP" => {:major => 5, :minor => 1},
"Windows 2000" => {:major => 5, :minor => 0}
}.freeze unless defined?(WIN_VERSIONS)
marketing_names = Array.new
# General Windows checks
WIN_VERSIONS.each do |k,v|
method_name = "#{k.gsub(/\s/, '_').downcase}?"
define_method(method_name) do
(@major_version == v[:major]) &&
(@minor_version == v[:minor]) &&
(v[:callable] ? v[:callable].call : true)
end
marketing_names << [k, method_name]
end
define_method(:marketing_name) do
marketing_names.each do |mn|
break mn[0] if self.send(mn[1])
end
end
# Server Type checks
%w{ core full datacenter }.each do |m|
define_method("server_#{m}?") do
if @sku
!(SKU[@sku][:name] =~ /#{m}/i).nil?
else
false
end
end
end
private
# Win32API call to GetSystemMetrics(SM_SERVERR2)
# returns: The build number if the system is Windows Server 2003 R2; otherwise, 0.
def sm_serverr2
@sm_serverr2 ||= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2)
end
# query WMI Win32_OperatingSystem for required OS info
def get_os_info
cols = %w{ Version ProductType OSProductSuite OperatingSystemSKU ServicePackMajorVersion ServicePackMinorVersion }
os_info = execute_wmi_query("select * from Win32_OperatingSystem").each.next
cols.map do |c|
begin
wmi_object_property(os_info, c)
rescue # OperatingSystemSKU doesn't exist in all versions of Windows
nil
end
end
end
end
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Library:: version
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require_relative 'wmi_helper'
require 'Win32API'
end
module Windows
class Version
# http://msdn.microsoft.com/en-us/library/ms724833(v=vs.85).aspx
# Suite Masks
# Microsoft BackOffice components are installed.
VER_SUITE_BACKOFFICE = 0x00000004 unless defined?(VER_SUITE_BACKOFFICE)
# Windows Server 2003, Web Edition is installed.
VER_SUITE_BLADE = 0x00000400 unless defined?(VER_SUITE_BLADE)
# Windows Server 2003, Compute Cluster Edition is installed.
VER_SUITE_COMPUTE_SERVER = 0x00004000 unless defined?(VER_SUITE_COMPUTE_SERVER)
# Windows Server 2008 Datacenter, Windows Server 2003, Datacenter Edition, or Windows 2000 Datacenter Server is installed.
VER_SUITE_DATACENTER = 0x00000080 unless defined?(VER_SUITE_DATACENTER)
# Windows Server 2008 Enterprise, Windows Server 2003, Enterprise Edition, or Windows 2000 Advanced Server is installed. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_ENTERPRISE = 0x00000002 unless defined?(VER_SUITE_ENTERPRISE)
# Windows XP Embedded is installed.
VER_SUITE_EMBEDDEDNT = 0x00000040 unless defined?(VER_SUITE_EMBEDDEDNT)
# Windows Vista Home Premium, Windows Vista Home Basic, or Windows XP Home Edition is installed.
VER_SUITE_PERSONAL = 0x00000200 unless defined?(VER_SUITE_PERSONAL)
# Remote Desktop is supported, but only one interactive session is supported. This value is set unless the system is running in application server mode.
VER_SUITE_SINGLEUSERTS = 0x00000100 unless defined?(VER_SUITE_SINGLEUSERTS)
# Microsoft Small Business Server was once installed on the system, but may have been upgraded to another version of Windows. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_SMALLBUSINESS = 0x00000001 unless defined?(VER_SUITE_SMALLBUSINESS)
# Microsoft Small Business Server is installed with the restrictive client license in force. Refer to the Remarks section for more information about this bit flag.
VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020 unless defined?(VER_SUITE_SMALLBUSINESS_RESTRICTED)
# Windows Storage Server 2003 R2 or Windows Storage Server 2003is installed.
VER_SUITE_STORAGE_SERVER = 0x00002000 unless defined?(VER_SUITE_STORAGE_SERVER)
# Terminal Services is installed. This value is always set.
# If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, the system is running in application server mode.
VER_SUITE_TERMINAL = 0x00000010 unless defined?(VER_SUITE_TERMINAL)
# Windows Home Server is installed.
VER_SUITE_WH_SERVER = 0x00008000 unless defined?(VER_SUITE_WH_SERVER)
# Product Type
# The system is a domain controller and the operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
VER_NT_DOMAIN_CONTROLLER = 0x0000002 unless defined?(VER_NT_DOMAIN_CONTROLLER)
# The operating system is Windows Server 2012, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, or Windows 2000 Server.
# Note that a server that is also a domain controller is reported as VER_NT_DOMAIN_CONTROLLER, not VER_NT_SERVER.
VER_NT_SERVER = 0x0000003 unless defined?(VER_NT_SERVER)
# The operating system is Windows 7, Windows Vista, Windows XP Professional, Windows XP Home Edition, or Windows 2000 Professional.
VER_NT_WORKSTATION = 0x0000001 unless defined?(VER_NT_WORKSTATION)
# GetSystemMetrics
# The build number if the system is Windows Server 2003 R2; otherwise, 0.
SM_SERVERR2 = 89 unless defined?(SM_SERVERR2)
# http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx
SKU = {
0x00000006 => { ms_const: 'PRODUCT_BUSINESS', name: 'Business' },
0x00000010 => { ms_const: 'PRODUCT_BUSINESS_N', name: 'Business N' },
0x00000012 => { ms_const: 'PRODUCT_CLUSTER_SERVER', name: 'HPC Edition' },
0x00000008 => { ms_const: 'PRODUCT_DATACENTER_SERVER', name: 'Server Datacenter (full installation)' },
0x0000000C => { ms_const: 'PRODUCT_DATACENTER_SERVER_CORE', name: 'Server Datacenter (core installation)' },
0x00000027 => { ms_const: 'PRODUCT_DATACENTER_SERVER_CORE_V', name: 'Server Datacenter without Hyper-V (core installation)' },
0x00000025 => { ms_const: 'PRODUCT_DATACENTER_SERVER_V', name: 'Server Datacenter without Hyper-V (full installation)' },
0x00000004 => { ms_const: 'PRODUCT_ENTERPRISE', name: 'Enterprise' },
0x00000046 => { ms_const: 'PRODUCT_ENTERPRISE_E', name: 'Not supported' },
0x0000001B => { ms_const: 'PRODUCT_ENTERPRISE_N', name: 'Enterprise N' },
0x0000000A => { ms_const: 'PRODUCT_ENTERPRISE_SERVER', name: 'Server Enterprise (full installation)' },
0x0000000E => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_CORE', name: 'Server Enterprise (core installation)' },
0x00000029 => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_CORE_V', name: 'Server Enterprise without Hyper-V (core installation)' },
0x0000000F => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_IA64', name: 'Server Enterprise for Itanium-based Systems' },
0x00000026 => { ms_const: 'PRODUCT_ENTERPRISE_SERVER_V', name: 'Server Enterprise without Hyper-V (full installation)' },
0x00000002 => { ms_const: 'PRODUCT_HOME_BASIC', name: 'Home Basic' },
0x00000043 => { ms_const: 'PRODUCT_HOME_BASIC_E', name: 'Not supported' },
0x00000005 => { ms_const: 'PRODUCT_HOME_BASIC_N', name: 'Home Basic N' },
0x00000003 => { ms_const: 'PRODUCT_HOME_PREMIUM', name: 'Home Premium' },
0x00000044 => { ms_const: 'PRODUCT_HOME_PREMIUM_E', name: 'Not supported' },
0x0000001A => { ms_const: 'PRODUCT_HOME_PREMIUM_N', name: 'Home Premium N' },
0x0000002A => { ms_const: 'PRODUCT_HYPERV', name: 'Microsoft Hyper-V Server' },
0x0000001E => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT', name: 'Windows Essential Business Server Management Server' },
0x00000020 => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING', name: 'Windows Essential Business Server Messaging Server' },
0x0000001F => { ms_const: 'PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY', name: 'Windows Essential Business Server Security Server' },
0x00000030 => { ms_const: 'PRODUCT_PROFESSIONAL', name: 'Professional' },
0x00000045 => { ms_const: 'PRODUCT_PROFESSIONAL_E', name: 'Not supported' },
0x00000031 => { ms_const: 'PRODUCT_PROFESSIONAL_N', name: 'Professional N' },
0x00000067 => { ms_const: 'PRODUCT_PROFESSIONAL_WMC', name: 'Professional with Media Center' },
0x00000018 => { ms_const: 'PRODUCT_SERVER_FOR_SMALLBUSINESS', name: 'Windows Server 2008 for Windows Essential Server Solutions' },
0x00000023 => { ms_const: 'PRODUCT_SERVER_FOR_SMALLBUSINESS_V', name: 'Windows Server 2008 without Hyper-V for Windows Essential Server Solutions' },
0x00000021 => { ms_const: 'PRODUCT_SERVER_FOUNDATION', name: 'Server Foundation' },
0x00000022 => { ms_const: 'PRODUCT_HOME_PREMIUM_SERVER', name: 'Windows Home Server 2011' },
0x00000032 => { ms_const: 'PRODUCT_SB_SOLUTION_SERVER', name: 'Windows Small Business Server 2011 Essentials' },
0x00000013 => { ms_const: 'PRODUCT_HOME_SERVER', name: 'Windows Storage Server 2008 R2 Essentials' },
0x00000009 => { ms_const: 'PRODUCT_SMALLBUSINESS_SERVER', name: 'Windows Small Business Server' },
0x00000038 => { ms_const: 'PRODUCT_SOLUTION_EMBEDDEDSERVER', name: 'Windows MultiPoint Server' },
0x00000007 => { ms_const: 'PRODUCT_STANDARD_SERVER', name: 'Server Standard (full installation)' },
0x0000000D => { ms_const: 'PRODUCT_STANDARD_SERVER_CORE', name: 'Server Standard (core installation)' },
0x00000028 => { ms_const: 'PRODUCT_STANDARD_SERVER_CORE_V', name: 'Server Standard without Hyper-V (core installation)' },
0x00000024 => { ms_const: 'PRODUCT_STANDARD_SERVER_V', name: 'Server Standard without Hyper-V (full installation)' },
0x0000000B => { ms_const: 'PRODUCT_STARTER', name: 'Starter' },
0x00000042 => { ms_const: 'PRODUCT_STARTER_E', name: 'Not supported' },
0x0000002F => { ms_const: 'PRODUCT_STARTER_N', name: 'Starter N' },
0x00000017 => { ms_const: 'PRODUCT_STORAGE_ENTERPRISE_SERVER', name: 'Storage Server Enterprise' },
0x00000014 => { ms_const: 'PRODUCT_STORAGE_EXPRESS_SERVER', name: 'Storage Server Express' },
0x00000015 => { ms_const: 'PRODUCT_STORAGE_STANDARD_SERVER', name: 'Storage Server Standard' },
0x00000016 => { ms_const: 'PRODUCT_STORAGE_WORKGROUP_SERVER', name: 'Storage Server Workgroup' },
0x00000000 => { ms_const: 'PRODUCT_UNDEFINED', name: 'An unknown product' },
0x00000001 => { ms_const: 'PRODUCT_ULTIMATE', name: 'Ultimate' },
0x00000047 => { ms_const: 'PRODUCT_ULTIMATE_E', name: 'Not supported' },
0x0000001C => { ms_const: 'PRODUCT_ULTIMATE_N', name: 'Ultimate N' },
0x00000011 => { ms_const: 'PRODUCT_WEB_SERVER', name: 'Web Server (full installation)' },
0x0000001D => { ms_const: 'PRODUCT_WEB_SERVER_CORE', name: 'Web Server (core installation)' }
}.freeze unless defined?(SKU)
attr_reader :major_version, :minor_version, :build_number, :service_pack_major_version, :service_pack_minor_version
attr_reader :version, :product_type, :product_suite, :sku
def initialize
unless RUBY_PLATFORM =~ /mswin|mingw32|windows/
fail NotImplementedError, 'only valid on Windows platform'
end
@version, @product_type, @product_suite, @sku, @service_pack_major_version, @service_pack_minor_version = get_os_info
@major_version, @minor_version, @build_number = version.split('.').map(&:to_i)
end
WIN_VERSIONS = {
'Windows Server 2012 R2' => { major: 6, minor: 3, callable: -> { @product_type != VER_NT_WORKSTATION } },
'Windows 8' => { major: 6, minor: 2, callable: -> { @product_type == VER_NT_WORKSTATION } },
'Windows Server 2012' => { major: 6, minor: 2, callable: -> { @product_type != VER_NT_WORKSTATION } },
'Windows 7' => { major: 6, minor: 1, callable: -> { @product_type == VER_NT_WORKSTATION } },
'Windows Server 2008 R2' => { major: 6, minor: 1, callable: -> { @product_type != VER_NT_WORKSTATION } },
'Windows Server 2008' => { major: 6, minor: 0, callable: -> { @product_type != VER_NT_WORKSTATION } },
'Windows Vista' => { major: 6, minor: 0, callable: -> { @product_type == VER_NT_WORKSTATION } },
'Windows Server 2003 R2' => { major: 5, minor: 2, callable: -> { Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) != 0 } },
'Windows Home Server' => { major: 5, minor: 2, callable: -> { (@product_suite & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER } },
'Windows Server 2003' => { major: 5, minor: 2, callable: -> { Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) == 0 } },
'Windows XP' => { major: 5, minor: 1 },
'Windows 2000' => { major: 5, minor: 0 }
}.freeze unless defined?(WIN_VERSIONS)
marketing_names = []
# General Windows checks
WIN_VERSIONS.each do |k, v|
method_name = "#{k.gsub(/\s/, '_').downcase}?"
define_method(method_name) do
(@major_version == v[:major]) &&
(@minor_version == v[:minor]) &&
(v[:callable] ? v[:callable].call : true)
end
marketing_names << [k, method_name]
end
define_method(:marketing_name) do
marketing_names.each do |mn|
break mn[0] if send(mn[1])
end
end
# Server Type checks
%w( core full datacenter ).each do |m|
define_method("server_#{m}?") do
if @sku
!(SKU[@sku][:name] =~ /#{m}/i).nil?
else
false
end
end
end
private
# Win32API call to GetSystemMetrics(SM_SERVERR2)
# returns: The build number if the system is Windows Server 2003 R2; otherwise, 0.
def sm_serverr2
@sm_serverr2 ||= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2)
end
# query WMI Win32_OperatingSystem for required OS info
def get_os_info
cols = %w( Version ProductType OSProductSuite OperatingSystemSKU ServicePackMajorVersion ServicePackMinorVersion )
os_info = execute_wmi_query('select * from Win32_OperatingSystem').each.next
cols.map do |c|
begin
wmi_object_property(os_info, c)
rescue # OperatingSystemSKU doesn't exist in all versions of Windows
nil
end
end
end
end
end

View File

@@ -1,87 +1,86 @@
# Try to include from core chef, if error then monkey patch it in.
begin
include Chef::Mixin::WindowsArchitectureHelper
rescue
Chef::Log.debug("Chef::Mixin::WindowsArchitectureHelper not in core version, Monkey patching in.")
require 'chef/exceptions'
require 'win32/api' if Chef::Platform.windows?
class Chef
module Mixin
module WindowsArchitectureHelper
def node_windows_architecture(node)
node['kernel']['machine'].to_sym
end
def wow64_architecture_override_required?(node, desired_architecture)
is_i386_windows_process? &&
node_windows_architecture(node) == :x86_64 &&
desired_architecture == :x86_64
end
def node_supports_windows_architecture?(node, desired_architecture)
assert_valid_windows_architecture!(desired_architecture)
return (node_windows_architecture(node) == :x86_64 ||
desired_architecture == :i386) ? true : false
end
def valid_windows_architecture?(architecture)
return (architecture == :x86_64) || (architecture == :i386)
end
def assert_valid_windows_architecture!(architecture)
if ! valid_windows_architecture?(architecture)
raise Chef::Exceptions::Win32ArchitectureIncorrect,
"The specified architecture was not valid. It must be one of :i386 or :x86_64"
end
end
def is_i386_windows_process?
Chef::Platform.windows? && 'X86'.casecmp(ENV['PROCESSOR_ARCHITECTURE']) == 0
end
def disable_wow64_file_redirection(node)
original_redirection_state = ['0'].pack('P')
if ((node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?)
win32_wow_64_disable_wow_64_fs_redirection =
::Win32::API.new('Wow64DisableWow64FsRedirection', 'P', 'L', 'kernel32')
succeeded = win32_wow_64_disable_wow_64_fs_redirection.call(original_redirection_state)
if succeeded == 0
raise Win32APIError "Failed to disable Wow64 file redirection"
end
end
original_redirection_state
end
def restore_wow64_file_redirection(node, original_redirection_state)
if ( (node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?)
win32_wow_64_revert_wow_64_fs_redirection =
::Win32::API.new('Wow64RevertWow64FsRedirection', 'P', 'L', 'kernel32')
succeeded = win32_wow_64_revert_wow_64_fs_redirection.call(original_redirection_state)
if succeeded == 0
raise Win32APIError "Failed to revert Wow64 file redirection"
end
end
end
end
end
end
end
# Making sure this library is available to Chef::Mixin::PowershellOut
# Required for clients that don't have Chef::Mixin::WindowsArchitectureHelper in
# core chef.
if ::Chef::Platform.windows?
require_relative 'powershell_out'
Chef::Mixin::PowershellOut.send(:include, Chef::Mixin::WindowsArchitectureHelper)
end
# Try to include from core chef, if error then monkey patch it in.
begin
include Chef::Mixin::WindowsArchitectureHelper
rescue
Chef::Log.debug('Chef::Mixin::WindowsArchitectureHelper not in core version, Monkey patching in.')
require 'chef/exceptions'
require 'win32/api' if Chef::Platform.windows?
class Chef
module Mixin
module WindowsArchitectureHelper
def node_windows_architecture(node)
node['kernel']['machine'].to_sym
end
def wow64_architecture_override_required?(node, desired_architecture)
i386_windows_process? &&
node_windows_architecture(node) == :x86_64 &&
desired_architecture == :x86_64
end
def node_supports_windows_architecture?(node, desired_architecture)
assert_valid_windows_architecture!(desired_architecture)
(node_windows_architecture(node) == :x86_64 ||
desired_architecture == :i386) ? true : false
end
def valid_windows_architecture?(architecture)
(architecture == :x86_64) || (architecture == :i386)
end
def assert_valid_windows_architecture!(architecture)
unless valid_windows_architecture?(architecture)
raise Chef::Exceptions::Win32ArchitectureIncorrect,
'The specified architecture was not valid. It must be one of :i386 or :x86_64'
end
end
def i386_windows_process?
Chef::Platform.windows? && 'X86'.casecmp(ENV['PROCESSOR_ARCHITECTURE']) == 0
end
def disable_wow64_file_redirection(node)
original_redirection_state = ['0'].pack('P')
if (node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?
win32_wow_64_disable_wow_64_fs_redirection =
::Win32::API.new('Wow64DisableWow64FsRedirection', 'P', 'L', 'kernel32')
succeeded = win32_wow_64_disable_wow_64_fs_redirection.call(original_redirection_state)
if succeeded == 0
raise Win32APIError 'Failed to disable Wow64 file redirection'
end
end
original_redirection_state
end
def restore_wow64_file_redirection(node, original_redirection_state)
if (node_windows_architecture(node) == :x86_64) && ::Chef::Platform.windows?
win32_wow_64_revert_wow_64_fs_redirection =
::Win32::API.new('Wow64RevertWow64FsRedirection', 'P', 'L', 'kernel32')
succeeded = win32_wow_64_revert_wow_64_fs_redirection.call(original_redirection_state)
if succeeded == 0
raise Win32APIError 'Failed to revert Wow64 file redirection'
end
end
end
end
end
end
end
# Making sure this library is available to Chef::Mixin::PowershellOut
# Required for clients that don't have Chef::Mixin::WindowsArchitectureHelper in
# core chef.
if ::Chef::Platform.windows?
require_relative 'powershell_out'
Chef::Mixin::PowershellOut.send(:include, Chef::Mixin::WindowsArchitectureHelper)
end

View File

@@ -1,148 +1,168 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Library:: helper
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'uri'
require 'Win32API' if Chef::Platform.windows?
require 'chef/exceptions'
module Windows
module Helper
AUTO_RUN_KEY = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'.freeze unless defined?(AUTO_RUN_KEY)
ENV_KEY = 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'.freeze unless defined?(ENV_KEY)
ExpandEnvironmentStrings = Win32API.new('kernel32', 'ExpandEnvironmentStrings', ['P', 'P', 'L'], 'L') if Chef::Platform.windows?
# returns windows friendly version of the provided path,
# ensures backslashes are used everywhere
def win_friendly_path(path)
path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || '\\') if path
end
# account for Window's wacky File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
# especially important for 32-bit processes (like Ruby) on a
# 64-bit instance of Windows.
def locate_sysnative_cmd(cmd)
if ::File.exists?("#{ENV['WINDIR']}\\sysnative\\#{cmd}")
"#{ENV['WINDIR']}\\sysnative\\#{cmd}"
elsif ::File.exists?("#{ENV['WINDIR']}\\system32\\#{cmd}")
"#{ENV['WINDIR']}\\system32\\#{cmd}"
else
cmd
end
end
# Create a feature provider dependent value object.
# mainly created becasue Windows Feature names are
# different based on whether dism.exe or servicemanagercmd.exe
# is used for installation
def value_for_feature_provider(provider_hash)
p = Chef::Platform.find_provider_for_node(node, :windows_feature)
key = p.to_s.downcase.split('::').last
provider_hash[key] || provider_hash[key.to_sym]
end
# singleton instance of the Windows Version checker
def win_version
@win_version ||= Windows::Version.new
end
# if a file is local it returns a windows friendly path version
# if a file is remote it caches it locally
def cached_file(source, checksum=nil, windows_path=true)
@installer_file_path ||= begin
if source =~ ::URI::ABS_URI && %w[ftp http https].include?(URI.parse(source).scheme)
uri = ::URI.parse(source)
cache_file_path = "#{Chef::Config[:file_cache_path]}/#{::File.basename(::URI.unescape(uri.path))}"
Chef::Log.debug("Caching a copy of file #{source} at #{cache_file_path}")
r = Chef::Resource::RemoteFile.new(cache_file_path, run_context)
r.source(source)
r.backup(false)
r.checksum(checksum) if checksum
r.run_action(:create)
else
cache_file_path = source
end
windows_path ? win_friendly_path(cache_file_path) : cache_file_path
end
end
# Expands the environment variables
def expand_env_vars(path)
# We pick 32k because that is the largest it could be:
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724265%28v=vs.85%29.aspx
buf = 0.chr * 32 * 1024 # 32k
if ExpandEnvironmentStrings.call(path.dup, buf, buf.length) == 0
raise Chef::Exceptions::Win32APIError, "Failed calling ExpandEnvironmentStrings (received 0)"
end
buf.strip
end
def is_package_installed?(package_name)
installed_packages.include?(package_name)
end
def installed_packages
@installed_packages || begin
installed_packages = {}
# Computer\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE)) #rescue nil
# 64-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0100))) #rescue nil
# 32-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0200))) #rescue nil
# Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_CURRENT_USER)) #rescue nil
installed_packages
end
end
private
def extract_installed_packages_from_key(hkey = ::Win32::Registry::HKEY_LOCAL_MACHINE, desired = ::Win32::Registry::Constants::KEY_READ)
uninstall_subkey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall'
packages = {}
begin
::Win32::Registry.open(hkey, uninstall_subkey, desired) do |reg|
reg.each_key do |key, wtime|
begin
k = reg.open(key, desired)
display_name = k["DisplayName"] rescue nil
version = k["DisplayVersion"] rescue "NO VERSION"
uninstall_string = k["UninstallString"] rescue nil
if display_name
packages[display_name] = {:name => display_name,
:version => version,
:uninstall_string => uninstall_string}
end
rescue ::Win32::Registry::Error
end
end
end
rescue ::Win32::Registry::Error
end
packages
end
end
end
Chef::Recipe.send(:include, Windows::Helper)
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Library:: helper
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'uri'
require 'Win32API' if Chef::Platform.windows?
require 'chef/exceptions'
module Windows
module Helper
AUTO_RUN_KEY = 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'.freeze unless defined?(AUTO_RUN_KEY)
ENV_KEY = 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'.freeze unless defined?(ENV_KEY)
ExpandEnvironmentStrings = Win32API.new('kernel32', 'ExpandEnvironmentStrings', %w(P P L), 'L') if Chef::Platform.windows? && !defined?(ExpandEnvironmentStrings)
# returns windows friendly version of the provided path,
# ensures backslashes are used everywhere
def win_friendly_path(path)
path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || '\\') if path
end
# account for Window's wacky File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
# especially important for 32-bit processes (like Ruby) on a
# 64-bit instance of Windows.
def locate_sysnative_cmd(cmd)
if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\#{cmd}")
"#{ENV['WINDIR']}\\sysnative\\#{cmd}"
elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\#{cmd}")
"#{ENV['WINDIR']}\\system32\\#{cmd}"
else
cmd
end
end
# Create a feature provider dependent value object.
# mainly created becasue Windows Feature names are
# different based on whether dism.exe or servicemanagercmd.exe
# is used for installation
def value_for_feature_provider(provider_hash)
p = Chef::Platform.find_provider_for_node(node, :windows_feature)
key = p.to_s.downcase.split('::').last
provider_hash[key] || provider_hash[key.to_sym]
end
# singleton instance of the Windows Version checker
def win_version
@win_version ||= Windows::Version.new
end
# Helper function to properly parse a URI
def as_uri(source)
URI.parse(source)
rescue URI::InvalidURIError
Chef::Log.warn("#{source} was an invalid URI. Trying to escape invalid characters")
URI.parse(URI.escape(source))
end
# if a file is local it returns a windows friendly path version
# if a file is remote it caches it locally
def cached_file(source, checksum = nil, windows_path = true)
@installer_file_path ||= begin
if source =~ /^(file|ftp|http|https):\/\//
uri = as_uri(source)
cache_file_path = "#{Chef::Config[:file_cache_path]}/#{::File.basename(::URI.unescape(uri.path))}"
Chef::Log.debug("Caching a copy of file #{source} at #{cache_file_path}")
r = Chef::Resource::RemoteFile.new(cache_file_path, run_context)
r.source(source)
r.backup(false)
r.checksum(checksum) if checksum
r.run_action(:create)
else
cache_file_path = source
end
windows_path ? win_friendly_path(cache_file_path) : cache_file_path
end
end
# Expands the environment variables
def expand_env_vars(path)
# We pick 32k because that is the largest it could be:
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724265%28v=vs.85%29.aspx
buf = 0.chr * 32 * 1024 # 32k
if ExpandEnvironmentStrings.call(path.dup, buf, buf.length) == 0
fail Chef::Exceptions::Win32APIError, 'Failed calling ExpandEnvironmentStrings (received 0)'
end
buf.strip
end
def is_package_installed?(package_name) # rubocop:disable Style/PredicateName
installed_packages.include?(package_name)
end
def installed_packages
@installed_packages || begin
installed_packages = {}
# Computer\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE)) # rescue nil
# 64-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0100))) # rescue nil
# 32-bit registry view
# Computer\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0200))) # rescue nil
# Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
installed_packages.merge!(extract_installed_packages_from_key(::Win32::Registry::HKEY_CURRENT_USER)) # rescue nil
installed_packages
end
end
private
def extract_installed_packages_from_key(hkey = ::Win32::Registry::HKEY_LOCAL_MACHINE, desired = ::Win32::Registry::Constants::KEY_READ)
uninstall_subkey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall'
packages = {}
begin
::Win32::Registry.open(hkey, uninstall_subkey, desired) do |reg|
reg.each_key do |key, _wtime|
begin
k = reg.open(key, desired)
display_name = begin
k['DisplayName']
rescue
nil
end
version = begin
k['DisplayVersion']
rescue
'NO VERSION'
end
uninstall_string = begin
k['UninstallString']
rescue
nil
end
if display_name
packages[display_name] = { name: display_name,
version: version,
uninstall_string: uninstall_string }
end
rescue ::Win32::Registry::Error
end
end
end
rescue ::Win32::Registry::Error
end
packages
end
end
end
Chef::Recipe.send(:include, Windows::Helper)

View File

@@ -1,224 +1,226 @@
require 'chef/resource/lwrp_base'
require 'chef/provider/lwrp_base'
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'win32/registry'
end
require 'chef/mixin/shell_out'
require 'chef/mixin/language'
class Chef
class Provider
class WindowsCookbookPackage < Chef::Provider::LWRPBase
include Chef::Mixin::ShellOut
include Windows::Helper
# the logic in all action methods mirror that of
# the Chef::Provider::Package which will make
# refactoring into core chef easy
action :install do
# If we specified a version, and it's not the current version, move to the specified version
if @new_resource.version != nil && @new_resource.version != @current_resource.version
install_version = @new_resource.version
# If it's not installed at all, install it
elsif @current_resource.version == nil
install_version = candidate_version
end
if install_version
Chef::Log.info("Installing #{@new_resource} version #{install_version}")
status = install_package(@new_resource.package_name, install_version)
if status
new_resource.updated_by_last_action(true)
end
end
end
action :upgrade do
if @current_resource.version != candidate_version
orig_version = @current_resource.version || "uninstalled"
Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
status = upgrade_package(@new_resource.package_name, candidate_version)
if status
new_resource.updated_by_last_action(true)
end
end
end
action :remove do
if removing_package?
Chef::Log.info("Removing #{@new_resource}")
remove_package(@current_resource.package_name, @new_resource.version)
new_resource.updated_by_last_action(true)
else
end
end
def removing_package?
if @current_resource.version.nil?
false # nothing to remove
elsif @new_resource.version.nil?
true # remove any version of a package
elsif @new_resource.version == @current_resource.version
true # remove the version we have
else
false # we don't have the version we want to remove
end
end
def expand_options(options)
options ? " #{options}" : ""
end
# these methods are the required overrides of
# a provider that extends from Chef::Provider::Package
# so refactoring into core Chef should be easy
def load_current_resource
@current_resource = Chef::Resource::WindowsPackage.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
@current_resource.version(nil)
unless current_installed_version.nil?
@current_resource.version(current_installed_version)
end
@current_resource
end
def current_installed_version
@current_installed_version ||= begin
if installed_packages.include?(@new_resource.package_name)
installed_packages[@new_resource.package_name][:version]
end
end
end
def candidate_version
@candidate_version ||= begin
@new_resource.version || 'latest'
end
end
def install_package(name,version)
Chef::Log.debug("Processing #{@new_resource} as a #{installer_type} installer.")
install_args = [cached_file(@new_resource.source, @new_resource.checksum), expand_options(unattended_installation_flags), expand_options(@new_resource.options)]
Chef::Log.info("Starting installation...this could take awhile.")
Chef::Log.debug "Install command: #{ sprintf(install_command_template, *install_args) }"
shell_out!(sprintf(install_command_template, *install_args), {:timeout => @new_resource.timeout, :returns => @new_resource.success_codes})
end
def remove_package(name, version)
uninstall_string = installed_packages[@new_resource.package_name][:uninstall_string]
Chef::Log.info("Registry provided uninstall string for #{@new_resource} is '#{uninstall_string}'")
uninstall_command = begin
if uninstall_string =~ /msiexec/i
"#{uninstall_string} /qn"
else
uninstall_string.gsub!('"','')
"start \"\" /wait /d\"#{::File.dirname(uninstall_string)}\" #{::File.basename(uninstall_string)}#{expand_options(@new_resource.options)} /S & exit %%%%ERRORLEVEL%%%%"
end
end
Chef::Log.info("Removing #{@new_resource} with uninstall command '#{uninstall_command}'")
shell_out!(uninstall_command, {:returns => @new_resource.success_codes})
end
private
def install_command_template
case installer_type
when :msi
"msiexec%2$s \"%1$s\"%3$s"
else
"start \"\" /wait \"%1$s\"%2$s%3$s & exit %%%%ERRORLEVEL%%%%"
end
end
# http://unattended.sourceforge.net/installers.php
def unattended_installation_flags
case installer_type
when :msi
# this is no-ui
"/qn /i"
when :installshield
"/s /sms"
when :nsis
"/S /NCRC"
when :inno
#"/sp- /silent /norestart"
"/verysilent /norestart"
when :wise
"/s"
else
end
end
def installer_type
@installer_type || begin
if @new_resource.installer_type
@new_resource.installer_type
else
basename = ::File.basename(cached_file(@new_resource.source, @new_resource.checksum))
if basename.split(".").last.downcase == "msi" # Microsoft MSI
:msi
else
# search the binary file for installer type
contents = ::Kernel.open(::File.expand_path(cached_file(@new_resource.source)), "rb") {|io| io.read } # TODO limit data read in
case contents
when /inno/i # Inno Setup
:inno
when /wise/i # Wise InstallMaster
:wise
when /nsis/i # Nullsoft Scriptable Install System
:nsis
else
# if file is named 'setup.exe' assume installshield
if basename == "setup.exe"
:installshield
else
raise Chef::Exceptions::AttributeNotFound, "installer_type could not be determined, please set manually"
end
end
end
end
end
end
end
end
end
class Chef
class Resource
class WindowsCookbookPackage < Chef::Resource::LWRPBase
if Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12')
provides :windows_package, os: "windows"
end
actions :install, :remove
default_action :install
attribute :package_name, :kind_of => String, :name_attribute => true
attribute :source, :kind_of => String, :required => true
attribute :version, :kind_of => String
attribute :options, :kind_of => String
attribute :installer_type, :kind_of => Symbol, :default => nil, :equal_to => [:msi, :inno, :nsis, :wise, :installshield, :custom]
attribute :checksum, :kind_of => String
attribute :timeout, :kind_of => Integer, :default => 600
attribute :success_codes, :kind_of => Array, :default => [0, 42, 127]
self.resource_name = 'windows_package'
def initialize(*args)
super
@provider = Chef::Provider::WindowsCookbookPackage
end
end
end
end
if Gem::Version.new(Chef::VERSION) < Gem::Version.new('12')
Chef::Resource.send(:remove_const, :WindowsPackage) if defined? Chef::Resource::WindowsPackage
Chef::Resource.const_set("WindowsPackage", Chef::Resource::WindowsCookbookPackage)
end
require 'chef/resource/lwrp_base'
require 'chef/provider/lwrp_base'
require 'win32/registry' if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'chef/mixin/shell_out'
require 'chef/mixin/language'
class Chef
class Provider
class WindowsCookbookPackage < Chef::Provider::LWRPBase
include Chef::Mixin::ShellOut
include Windows::Helper
# the logic in all action methods mirror that of
# the Chef::Provider::Package which will make
# refactoring into core chef easy
action :install do
# If we specified a version, and it's not the current version, move to the specified version
if !@new_resource.version.nil? && @new_resource.version != @current_resource.version
install_version = @new_resource.version
# If it's not installed at all, install it
elsif @current_resource.version.nil?
install_version = candidate_version
end
if install_version
Chef::Log.info("Installing #{@new_resource} version #{install_version}")
status = install_package(@new_resource.package_name, install_version)
new_resource.updated_by_last_action(true) if status
end
end
action :upgrade do
if @current_resource.version != candidate_version
orig_version = @current_resource.version || 'uninstalled'
Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
status = upgrade_package(@new_resource.package_name, candidate_version)
new_resource.updated_by_last_action(true) if status
end
end
action :remove do
if removing_package?
Chef::Log.info("Removing #{@new_resource}")
remove_package(@current_resource.package_name, @new_resource.version)
new_resource.updated_by_last_action(true)
end
end
def removing_package?
if @current_resource.version.nil?
false # nothing to remove
elsif @new_resource.version.nil?
true # remove any version of a package
elsif @new_resource.version == @current_resource.version
true # remove the version we have
else
false # we don't have the version we want to remove
end
end
def expand_options(options)
options ? " #{options}" : ''
end
# these methods are the required overrides of
# a provider that extends from Chef::Provider::Package
# so refactoring into core Chef should be easy
def load_current_resource
@current_resource = Chef::Resource::WindowsPackage.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
@current_resource.version(nil)
unless current_installed_version.nil?
@current_resource.version(current_installed_version)
end
@current_resource
end
def current_installed_version
@current_installed_version ||= begin
if installed_packages.include?(@new_resource.package_name)
installed_packages[@new_resource.package_name][:version]
end
end
end
def candidate_version
@candidate_version ||= begin
@new_resource.version || 'latest'
end
end
def install_package(_name, _version)
Chef::Log.debug("Processing #{@new_resource} as a #{installer_type} installer.")
install_args = [cached_file(@new_resource.source, @new_resource.checksum), expand_options(unattended_installation_flags), expand_options(@new_resource.options)]
Chef::Log.info('Starting installation...this could take awhile.')
Chef::Log.debug "Install command: #{sprintf(install_command_template, *install_args)}"
shell_out!(sprintf(install_command_template, *install_args), timeout: @new_resource.timeout, returns: @new_resource.success_codes)
end
def remove_package(_name, _version)
uninstall_string = installed_packages[@new_resource.package_name][:uninstall_string]
Chef::Log.info("Registry provided uninstall string for #{@new_resource} is '#{uninstall_string}'")
uninstall_command = begin
if uninstall_string =~ /msiexec/i
"#{uninstall_string} /qn"
else
uninstall_string.delete!('"')
"start \"\" /wait /d\"#{::File.dirname(uninstall_string)}\" #{::File.basename(uninstall_string)}#{expand_options(@new_resource.options)} /S & exit %%%%ERRORLEVEL%%%%"
end
end
Chef::Log.info("Removing #{@new_resource} with uninstall command '#{uninstall_command}'")
shell_out!(uninstall_command, { returns: @new_resource.success_codes })
end
private
def install_command_template
case installer_type
when :msi
"msiexec%2$s \"%1$s\"%3$s"
else
"start \"\" /wait \"%1$s\"%2$s%3$s & exit %%%%ERRORLEVEL%%%%"
end
end
# http://unattended.sourceforge.net/installers.php
def unattended_installation_flags
case installer_type
when :msi
# this is no-ui
'/qn /i'
when :installshield
'/s /sms'
when :nsis
'/S /NCRC'
when :inno
# "/sp- /silent /norestart"
'/verysilent /norestart'
when :wise
'/s'
end
end
def installer_type
@installer_type || begin
if @new_resource.installer_type
@new_resource.installer_type
else
basename = ::File.basename(cached_file(@new_resource.source, @new_resource.checksum))
if basename.split('.').last.downcase == 'msi' # Microsoft MSI
:msi
else
# search the binary file for installer type
contents = ::Kernel.open(::File.expand_path(cached_file(@new_resource.source)), 'rb', &:read) # TODO: limit data read in
case contents
when /inno/i # Inno Setup
:inno
when /wise/i # Wise InstallMaster
:wise
when /nsis/i # Nullsoft Scriptable Install System
:nsis
else
# if file is named 'setup.exe' assume installshield
if basename == 'setup.exe'
:installshield
else
fail Chef::Exceptions::AttributeNotFound, 'installer_type could not be determined, please set manually'
end
end
end
end
end
end
end
end
end
class Chef
class Resource
class WindowsCookbookPackage < Chef::Resource::LWRPBase
if Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12.4.0')
provides :windows_package, os: 'windows', override: true
elsif Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12')
provides :windows_package, os: 'windows'
end
actions :install, :remove
default_action :install
attribute :package_name, kind_of: String, name_attribute: true
attribute :source, kind_of: String, required: true
attribute :version, kind_of: String
attribute :options, kind_of: String
attribute :installer_type, kind_of: Symbol, default: nil, equal_to: [:msi, :inno, :nsis, :wise, :installshield, :custom]
attribute :checksum, kind_of: String
attribute :timeout, kind_of: Integer, default: 600
attribute :success_codes, kind_of: Array, default: [0, 42, 127]
self.resource_name = 'windows_package'
def initialize(*args)
super
@provider = Chef::Provider::WindowsCookbookPackage
end
end
end
end
if Gem::Version.new(Chef::VERSION) < Gem::Version.new('12')
# this wires up the cookbook version of the windows_package resource as Chef::Resource::WindowsPackage,
# which is kinda hella janky
Chef::Resource.send(:remove_const, :WindowsPackage) if defined? Chef::Resource::WindowsPackage
Chef::Resource.const_set('WindowsPackage', Chef::Resource::WindowsCookbookPackage)
else
if Chef.respond_to?(:set_resource_priority_array)
# this wires up the dynamic resource resolver to favor the cookbook version of windows_package over
# the internal version (but the internal Chef::Resource::WindowsPackage is still the internal version
# and a wrapper cookbook can override this e.g. for users that want to use the windows cookbook but
# want the internal windows_package resource)
Chef.set_resource_priority_array(:windows_package, [Chef::Resource::WindowsCookbookPackage], platform: 'windows')
end
end

View File

@@ -1,94 +1,103 @@
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Library:: windows_privileged
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'windows/error'
require 'windows/registry'
require 'windows/process'
require 'windows/security'
end
#helpers for Windows API calls that require privilege adjustments
class Chef
class WindowsPrivileged
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
include Windows::Error
include Windows::Registry
include Windows::Process
include Windows::Security
end
#File -> Load Hive... in regedit.exe
def reg_load_key(name, file)
run(SE_BACKUP_NAME, SE_RESTORE_NAME) do
rc = RegLoadKey(HKEY_USERS, name.to_s, file)
if rc == ERROR_SUCCESS
return true
elsif rc == ERROR_SHARING_VIOLATION
return false
else
raise get_last_error(rc)
end
end
end
#File -> Unload Hive... in regedit.exe
def reg_unload_key(name)
run(SE_BACKUP_NAME, SE_RESTORE_NAME) do
rc = RegUnLoadKey(HKEY_USERS, name.to_s)
if rc != ERROR_SUCCESS
raise get_last_error(rc)
end
end
end
def run(*privileges)
token = [0].pack('L')
unless OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, token)
raise get_last_error
end
token = token.unpack('L')[0]
privileges.each do |name|
unless adjust_privilege(token, name, SE_PRIVILEGE_ENABLED)
raise get_last_error
end
end
begin
yield
ensure #disable privs
privileges.each do |name|
adjust_privilege(token, name, 0)
end
end
end
def adjust_privilege(token, priv, attr=0)
luid = [0,0].pack('Ll')
if LookupPrivilegeValue(nil, priv, luid)
new_state = [1, luid.unpack('Ll'), attr].flatten.pack('LLlL')
AdjustTokenPrivileges(token, 0, new_state, new_state.size, 0, 0)
end
end
end
end
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Library:: windows_privileged
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# helpers for Windows API calls that require privilege adjustments
class Chef
class WindowsPrivileged
# File -> Load Hive... in regedit.exe
def reg_load_key(name, file)
load_deps
run(SE_BACKUP_NAME, SE_RESTORE_NAME) do
rc = RegLoadKey(HKEY_USERS, name.to_s, file)
if rc == ERROR_SUCCESS
return true
elsif rc == ERROR_SHARING_VIOLATION
return false
else
fail get_last_error(rc)
end
end
end
# File -> Unload Hive... in regedit.exe
def reg_unload_key(name)
load_deps
run(SE_BACKUP_NAME, SE_RESTORE_NAME) do
rc = RegUnLoadKey(HKEY_USERS, name.to_s)
fail get_last_error(rc) if rc != ERROR_SUCCESS
end
end
def run(*privileges)
load_deps
token = [0].pack('L')
unless OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, token)
fail get_last_error
end
token = token.unpack('L')[0]
privileges.each do |name|
unless adjust_privilege(token, name, SE_PRIVILEGE_ENABLED)
fail get_last_error
end
end
begin
yield
ensure # disable privs
privileges.each do |name|
adjust_privilege(token, name, 0)
end
end
end
def adjust_privilege(token, priv, attr = 0)
load_deps
luid = [0, 0].pack('Ll')
if LookupPrivilegeValue(nil, priv, luid)
new_state = [1, luid.unpack('Ll'), attr].flatten.pack('LLlL')
AdjustTokenPrivileges(token, 0, new_state, new_state.size, 0, 0)
end
end
private
def load_deps
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'windows/error'
require 'windows/registry'
require 'windows/process'
require 'windows/security'
include Windows::Error
include Windows::Registry
include Windows::Process
include Windows::Security
end
end
end
end

View File

@@ -1,32 +1,32 @@
#
# Author:: Adam Edwards (<adamed@chef.io>)
#
# Copyright:: 2014, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'win32ole'
def execute_wmi_query(wmi_query)
wmi = ::WIN32OLE.connect("winmgmts://")
result = wmi.ExecQuery(wmi_query)
return nil unless result.each.count > 0
result
end
def wmi_object_property(wmi_object, wmi_property)
wmi_object.send(wmi_property)
end
end
#
# Author:: Adam Edwards (<adamed@chef.io>)
#
# Copyright:: 2014-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
require 'win32ole'
def execute_wmi_query(wmi_query)
wmi = ::WIN32OLE.connect('winmgmts://')
result = wmi.ExecQuery(wmi_query)
return nil unless result.each.count > 0
result
end
def wmi_object_property(wmi_object, wmi_property)
wmi_object.send(wmi_property)
end
end

File diff suppressed because one or more lines are too long

View File

@@ -1,33 +1,33 @@
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: auto_run
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
action :create do
windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do
values new_resource.name => "\"#{new_resource.program}\" #{new_resource.args}"
end
end
action :remove do
windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do
values new_resource.name => ''
action :remove
end
end
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: auto_run
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
action :create do
windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do
values new_resource.name => "\"#{new_resource.program}\" #{new_resource.args}"
end
end
action :remove do
windows_registry 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' do
values new_resource.name => ''
action :remove
end
end

View File

@@ -1,63 +1,64 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windws
# Provider:: batch
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
require 'tempfile'
require 'chef/resource/execute'
action :run do
begin
script_file.puts(@new_resource.code)
script_file.close
set_owner_and_group
# cwd hax...shell_out on windows needs to support proper 'cwd'
# follow CHEF-2357 for more
cwd = @new_resource.cwd ? "cd \"#{@new_resource.cwd}\" & " : ""
r = Chef::Resource::Execute.new(@new_resource.name, run_context)
r.user(@new_resource.user)
r.group(@new_resource.group)
r.command("#{cwd}call \"#{script_file.path}\" #{@new_resource.flags}")
r.creates(@new_resource.creates)
r.returns(@new_resource.returns)
r.run_action(:run)
@new_resource.updated_by_last_action(r.updated_by_last_action?)
ensure
unlink_script_file
end
end
private
def set_owner_and_group
# FileUtils itself implements a no-op if +user+ or +group+ are nil
# You can prove this by running FileUtils.chown(nil,nil,'/tmp/file')
# as an unprivileged user.
FileUtils.chown(@new_resource.user, @new_resource.group, script_file.path)
end
def script_file
@script_file ||= Tempfile.open(['chef-script', '.bat'])
end
def unlink_script_file
@script_file && @script_file.close!
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windws
# Provider:: batch
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
require 'tempfile'
require 'chef/resource/execute'
action :run do
begin
script_file.puts(@new_resource.code)
script_file.close
set_owner_and_group
# cwd hax...shell_out on windows needs to support proper 'cwd'
# follow CHEF-2357 for more
cwd = @new_resource.cwd ? "cd \"#{@new_resource.cwd}\" & " : ''
r = Chef::Resource::Execute.new(@new_resource.name, run_context)
r.user(@new_resource.user)
r.group(@new_resource.group)
r.command("#{cwd}call \"#{script_file.path}\" #{@new_resource.flags}")
r.creates(@new_resource.creates)
r.returns(@new_resource.returns)
r.run_action(:run)
@new_resource.updated_by_last_action(r.updated_by_last_action?)
ensure
unlink_script_file
end
end
private
def set_owner_and_group
# FileUtils itself implements a no-op if +user+ or +group+ are nil
# You can prove this by running FileUtils.chown(nil,nil,'/tmp/file')
# as an unprivileged user.
FileUtils.chown(@new_resource.user, @new_resource.group, script_file.path)
end
def script_file
@script_file ||= Tempfile.open(['chef-script', '.bat'])
end
def unlink_script_file
@script_file && @script_file.close!
end

View File

@@ -0,0 +1,178 @@
#
# Author:: Richard Lavey (richard.lavey@calastone.com)
# Cookbook Name:: windows
# Provider:: certificate
#
# Copyright:: 2015, Calastone Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See this for info on certutil
# https://technet.microsoft.com/en-gb/library/cc732443.aspx
include Windows::Helper
# Support whyrun
def whyrun_supported?
true
end
use_inline_resources
action :create do
hash = '$cert.GetCertHashString()'
code_script = cert_script(true) <<
within_store_script { |store| store + '.Add($cert)' } <<
acl_script(hash)
guard_script = cert_script(false) <<
cert_exists_script(hash)
powershell_script @new_resource.name do
guard_interpreter :powershell_script
convert_boolean_return true
code code_script
not_if guard_script
end
end
# acl_add is a modify-if-exists operation : not idempotent
action :acl_add do
if ::File.exist?(@new_resource.source)
hash = '$cert.GetCertHashString()'
code_script = cert_script(false)
guard_script = cert_script(false)
else
# make sure we have no spaces in the hash string
hash = "\"#{@new_resource.source.gsub(/\s/, '')}\""
code_script = ''
guard_script = ''
end
code_script << acl_script(hash)
guard_script << cert_exists_script(hash)
powershell_script @new_resource.name do
guard_interpreter :powershell_script
convert_boolean_return true
code code_script
only_if guard_script
end
end
action :delete do
# do we have a hash or a subject?
# TODO: It's a bit annoying to know the thumbprint of a cert you want to remove when you already
# have the file. Support reading the hash directly from the file if provided.
if @new_resource.source.match(/^[a-fA-F0-9]{40}$/)
search = "Thumbprint -eq '#{@new_resource.source}'"
else
search = "Subject -like '*#{@new_resource.source.sub(/\*/, '`*')}*'" # escape any * in the source
end
cert_command = "Get-ChildItem Cert:\\#{@location}\\#{@new_resource.store_name} | where { $_.#{search} }"
code_script = within_store_script do |store|
<<-EOH
foreach ($c in #{cert_command})
{
#{store}.Remove($c)
}
EOH
end
guard_script = "@(#{cert_command}).Count -gt 0\n"
powershell_script @new_resource.name do
guard_interpreter :powershell_script
convert_boolean_return true
code code_script
only_if guard_script
end
end
def load_current_resource
# Currently we don't read out the cert acl here and converge it in a very Chef-y way.
# We also don't read if the private key is available or populate "exists". This means
# that if you converged a cert without persisting the private key once, we won't do it
# again, even if you have a cert with the keys now.
# TODO: Make this more Chef-y and follow a more state-based patten of convergence.
@current_resource = Chef::Resource::WindowsCertificate.new(@new_resource.name)
# TODO: Change to allow source to be read from the cookbook. It makes testing
# and loading certs from the cookbook much easier.
@current_resource.source(@new_resource.source)
@current_resource.pfx_password(@new_resource.pfx_password)
@current_resource.private_key_acl(@new_resource.private_key_acl)
@current_resource.store_name(@new_resource.store_name)
@current_resource.user_store(@new_resource.user_store)
@location = @current_resource.user_store ? 'CurrentUser' : 'LocalMachine'
end
private
def cert_script(persist)
cert_script = '$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2'
file = win_friendly_path(@new_resource.source)
cert_script << " \"#{file}\""
if ::File.extname(file.downcase) == '.pfx'
cert_script << ", \"#{@new_resource.pfx_password}\""
if persist && @new_resource.user_store
cert_script << ', [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet'
elsif persist
cert_script << ', ([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeyset)'
end
end
cert_script << "\n"
end
def cert_exists_script(hash)
<<-EOH
$hash = #{hash}
Test-Path "Cert:\\#{@location}\\#{@new_resource.store_name}\\$hash"
EOH
end
def within_store_script
inner_script = yield '$store'
<<-EOH
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "#{@new_resource.store_name}", ([System.Security.Cryptography.X509Certificates.StoreLocation]::#{@location})
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
#{inner_script}
$store.Close()
EOH
end
def acl_script(hash)
return '' if @new_resource.private_key_acl.nil? || @new_resource.private_key_acl.length == 0
# this PS came from http://blogs.technet.com/b/operationsguy/archive/2010/11/29/provide-access-to-private-keys-commandline-vs-powershell.aspx
# and from https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778(v=vs.85).aspx
set_acl_script = <<-EOH
$hash = #{hash}
$storeCert = Get-ChildItem "cert:\\#{@location}\\#{@new_resource.store_name}\\$hash"
if ($storeCert -eq $null) { throw 'no key exists.' }
$keyname = $storeCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
if ($keyname -eq $null) { throw 'no private key exists.' }
if ($storeCert.PrivateKey.CspKeyContainerInfo.MachineKeyStore)
{
$fullpath = "$Env:ProgramData\\Microsoft\\Crypto\\RSA\\MachineKeys\\$keyname"
}
else
{
$currentUser = New-Object System.Security.Principal.NTAccount($Env:UserDomain, $Env:UserName)
$userSID = $currentUser.Translate([System.Security.Principal.SecurityIdentifier]).Value
$fullpath = "$Env:ProgramData\\Microsoft\\Crypto\\RSA\\$userSID\\$keyname"
}
EOH
@new_resource.private_key_acl.each do |name|
set_acl_script << "$uname='#{name}'; icacls $fullpath /grant $uname`:RX\n"
end
set_acl_script
end

View File

@@ -0,0 +1,133 @@
#
# Author:: Richard Lavey (richard.lavey@calastone.com)
# Cookbook Name:: windows
# Provider:: certificate_binding
#
# Copyright:: 2015, Calastone Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See https://msdn.microsoft.com/en-us/library/windows/desktop/cc307236%28v=vs.85%29.aspx for netsh info
include Chef::Mixin::ShellOut
include Chef::Mixin::PowershellOut
include Windows::Helper
# Support whyrun
def whyrun_supported?
true
end
action :create do
hash = @new_resource.name_kind == :subject ? getHashFromSubject : @new_resource.cert_name
if @current_resource.exists
needsChange = (hash.casecmp(@current_hash) != 0)
if needsChange
converge_by("Changing #{@current_resource.address}:#{@current_resource.port}") do
deleteBinding
setBinding hash
end
else
Chef::Log.debug("#{@current_resource.address}:#{@current_resource.port} already bound to #{hash} - nothing to do")
end
else
converge_by("Binding #{@current_resource.address}:#{@current_resource.port}") do
setBinding hash
end
end
end
action :delete do
if @current_resource.exists
converge_by("Deleting #{@current_resource.address}:#{@current_resource.port}") do
deleteBinding
end
else
Chef::Log.debug("#{@current_resource.address}:#{@current_resource.port} not bound - nothing to do")
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsCertificateBinding.new(@new_resource.name)
@current_resource.cert_name(@new_resource.cert_name)
@current_resource.name_kind(@new_resource.name_kind)
@current_resource.address(@new_resource.address)
@current_resource.port(@new_resource.port)
@current_resource.store_name(@new_resource.store_name)
@command = locate_sysnative_cmd('netsh.exe')
getCurrentHash
end
private
def getCurrentHash
cmd = shell_out("#{@command} http show sslcert ipport=#{@current_resource.address}:#{@current_resource.port}")
Chef::Log.debug "netsh reports: #{cmd.stdout}"
if cmd.exitstatus == 0
m = cmd.stdout.scan(/Certificate Hash\s+:\s?([A-Fa-f0-9]{40})/)
if m.length == 0
fail "Failed to extract hash from command output #{cmd.stdout}"
else
@current_hash = m[0][0]
@current_resource.exists = true
end
else
@current_resource.exists = false
end
end
def setBinding(hash)
cmd = "#{@command} http add sslcert"
cmd << " ipport=#{@current_resource.address}:#{@current_resource.port}"
cmd << " certhash=#{hash}"
cmd << " appid=#{@current_resource.app_id}"
cmd << " certstorename=#{@current_resource.store_name}"
checkHash hash
shell_out!(cmd)
end
def deleteBinding
shell_out!("#{@command} http delete sslcert ipport=#{@current_resource.address}:#{@current_resource.port}")
end
def checkHash(hash)
p = powershell_out!("Test-Path \"cert:\\LocalMachine\\#{@current_resource.store_name}\\#{hash}\"")
unless p.stderr.empty? && p.stdout =~ /True/i
fail "A Cert with hash of #{hash} doesn't exist in keystore LocalMachine\\#{@current_resource.store_name}"
end
nil
end
def getHashFromSubject
# escape wildcard subject name (*.acme.com)
subject = @current_resource.cert_name.sub(/\*/, '`*')
ps_script = "& { gci cert:\\localmachine\\#{@current_resource.store_name} | where subject -like '*#{subject}*' | select -first 1 -expandproperty Thumbprint }"
Chef::Log.debug "Running PS script #{ps_script}"
p = powershell_out!(ps_script)
if !p.stderr.nil? && p.stderr.length > 0
fail "#{ps_script} failed with #{p.stderr}"
elsif p.stdout.nil? || p.stdout.length == 0
fail "Couldn't find thumbprint for subject #{@current_resource.cert_name}"
end
p.stdout.strip
end

View File

@@ -1,64 +1,65 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: feature_dism
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::ShellOut
include Windows::Helper
def install_feature(name)
addsource = @new_resource.source ? "/LimitAccess /Source:\"#{@new_resource.source}\"" : ""
addall = @new_resource.all ? "/All" : ""
shell_out!("#{dism} /online /enable-feature /featurename:#{@new_resource.feature_name} /norestart #{addsource} #{addall}", {:returns => [0,42,127,3010]})
end
def remove_feature(name)
shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /norestart", {:returns => [0,42,127,3010]})
end
def delete_feature(name)
if win_version.major_version >= 6 and win_version.minor_version >=2
shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /Remove /norestart", {:returns => [0,42,127,3010]})
else
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} :delete action not support on #{win_version.sku}"
end
end
def installed?
@installed ||= begin
cmd = shell_out("#{dism} /online /Get-Features", {:returns => [0,42,127]})
cmd.stderr.empty? && (cmd.stdout =~ /^Feature Name : #{@new_resource.feature_name}.?$\n^State : Enabled.?$/i)
end
end
def available?
@available ||= begin
cmd = shell_out("#{dism} /online /Get-Features", {:returns => [0,42,127]})
cmd.stderr.empty? && (cmd.stdout !~ /^Feature Name : #{@new_resource.feature_name}.?$\n^State : .* with payload removed.?$/i)
end
end
private
# account for File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
def dism
@dism ||= begin
locate_sysnative_cmd("dism.exe")
end
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: feature_dism
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::ShellOut
include Windows::Helper
def install_feature(_name)
addsource = @new_resource.source ? "/LimitAccess /Source:\"#{@new_resource.source}\"" : ''
addall = @new_resource.all ? '/All' : ''
shell_out!("#{dism} /online /enable-feature /featurename:#{@new_resource.feature_name} /norestart #{addsource} #{addall}", returns: [0, 42, 127, 3010])
end
def remove_feature(_name)
shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /norestart", returns: [0, 42, 127, 3010])
end
def delete_feature(_name)
if win_version.major_version >= 6 && win_version.minor_version >= 2
shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /Remove /norestart", returns: [0, 42, 127, 3010])
else
fail Chef::Exceptions::UnsupportedAction, "#{self} :delete action not support on #{win_version.sku}"
end
end
def installed?
@installed ||= begin
cmd = shell_out("#{dism} /online /Get-Features", returns: [0, 42, 127])
cmd.stderr.empty? && (cmd.stdout =~ /^Feature Name : #{@new_resource.feature_name}.?$\n^State : Enabled.?$/i)
end
end
def available?
@available ||= begin
cmd = shell_out("#{dism} /online /Get-Features", returns: [0, 42, 127])
cmd.stderr.empty? && (cmd.stdout !~ /^Feature Name : #{@new_resource.feature_name}.?$\n^State : .* with payload removed.?$/i)
end
end
private
# account for File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
def dism
@dism ||= begin
locate_sysnative_cmd('dism.exe')
end
end

View File

@@ -1,38 +1,38 @@
#
# Author:: Greg Zapp (<greg.zapp@gmail.com>)
# Cookbook Name:: windows
# Provider:: feature_powershell
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::PowershellOut
include Windows::Helper
def install_feature(name)
cmd = powershell_out("Install-WindowsFeature #{@new_resource.feature_name}")
Chef::Log.info(cmd.stdout)
end
def remove_feature(name)
cmd = powershell_out("Uninstall-WindowsFeature #{@new_resource.feature_name}")
Chef::Log.info(cmd.stdout)
end
def delete_feature(name)
cmd = powershell_out("Uninstall-WindowsFeature #{@new_resource.feature_name} -Remove")
Chef::Log.info(cmd.stdout)
end
def installed?
@installed ||= begin
cmd = powershell_out("Get-WindowsFeature #{@new_resource.feature_name} | Select Installed | % { Write-Host $_.Installed }")
cmd.stderr.empty? && cmd.stdout =~ /True/i
end
end
def available?
@available ||= begin
cmd = powershell_out("Get-WindowsFeature #{@new_resource.feature_name}")
cmd.stderr.empty? && cmd.stdout !~ /Removed/i
end
end
#
# Author:: Greg Zapp (<greg.zapp@gmail.com>)
# Cookbook Name:: windows
# Provider:: feature_powershell
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::PowershellOut
include Windows::Helper
def install_feature(_name)
cmd = powershell_out("Install-WindowsFeature #{@new_resource.feature_name}")
Chef::Log.info(cmd.stdout)
end
def remove_feature(_name)
cmd = powershell_out("Uninstall-WindowsFeature #{@new_resource.feature_name}")
Chef::Log.info(cmd.stdout)
end
def delete_feature(_name)
cmd = powershell_out("Uninstall-WindowsFeature #{@new_resource.feature_name} -Remove")
Chef::Log.info(cmd.stdout)
end
def installed?
@installed ||= begin
cmd = powershell_out("Get-WindowsFeature #{@new_resource.feature_name} | Select Installed | % { Write-Host $_.Installed }")
cmd.stderr.empty? && cmd.stdout =~ /True/i
end
end
def available?
@available ||= begin
cmd = powershell_out("Get-WindowsFeature #{@new_resource.feature_name}")
cmd.stderr.empty? && cmd.stdout !~ /Removed/i
end
end

View File

@@ -1,61 +1,61 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: feature_servermanagercmd
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::ShellOut
include Windows::Helper
# Exit codes are listed at http://technet.microsoft.com/en-us/library/cc749128(v=ws.10).aspx
def check_reboot(result, feature)
if result.exitstatus == 3010 # successful, but needs reboot
node.run_state[:reboot_requested] = true
Chef::Log.warn("Require reboot to install #{feature}")
elsif result.exitstatus == 1001 # failure, but needs reboot before we can do anything else
node.run_state[:reboot_requested] = true
Chef::Log.warn("Failed installing #{feature} and need to reboot")
end
result.error! # throw for any other bad results. The above results will also get raised, and should cause a reboot via the handler.
end
def install_feature(name)
check_reboot(shell_out("#{servermanagercmd} -install #{@new_resource.feature_name}", {:returns => [0,42,127,1003,3010]}), @new_resource.feature_name)
end
def remove_feature(name)
check_reboot(shell_out("#{servermanagercmd} -remove #{@new_resource.feature_name}", {:returns => [0,42,127,1003,3010]}), @new_resource.feature_name)
end
def installed?
@installed ||= begin
cmd = shell_out("#{servermanagercmd} -query", {:returns => [0,42,127,1003]})
cmd.stderr.empty? && (cmd.stdout =~ /^\s*?\[X\]\s.+?\s\[#{@new_resource.feature_name}\]\s*$/i)
end
end
private
# account for File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
def servermanagercmd
@servermanagercmd ||= begin
locate_sysnative_cmd("servermanagercmd.exe")
end
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: feature_servermanagercmd
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::ShellOut
include Windows::Helper
# Exit codes are listed at http://technet.microsoft.com/en-us/library/cc749128(v=ws.10).aspx
def check_reboot(result, feature)
if result.exitstatus == 3010 # successful, but needs reboot
node.run_state[:reboot_requested] = true
Chef::Log.warn("Require reboot to install #{feature}")
elsif result.exitstatus == 1001 # failure, but needs reboot before we can do anything else
node.run_state[:reboot_requested] = true
Chef::Log.warn("Failed installing #{feature} and need to reboot")
end
result.error! # throw for any other bad results. The above results will also get raised, and should cause a reboot via the handler.
end
def install_feature(_name)
check_reboot(shell_out("#{servermanagercmd} -install #{@new_resource.feature_name}", returns: [0, 42, 127, 1003, 3010]), @new_resource.feature_name)
end
def remove_feature(_name)
check_reboot(shell_out("#{servermanagercmd} -remove #{@new_resource.feature_name}", returns: [0, 42, 127, 1003, 3010]), @new_resource.feature_name)
end
def installed?
@installed ||= begin
cmd = shell_out("#{servermanagercmd} -query", returns: [0, 42, 127, 1003])
cmd.stderr.empty? && (cmd.stdout =~ /^\s*?\[X\]\s.+?\s\[#{@new_resource.feature_name}\]\s*$/i)
end
end
private
# account for File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
def servermanagercmd
@servermanagercmd ||= begin
locate_sysnative_cmd('servermanagercmd.exe')
end
end

View File

@@ -1,69 +1,69 @@
#
# Author:: Sander Botman <sbotman@schubergphilis.com>
# Cookbook Name:: windows
# Provider:: font
#
# Copyright:: 2014, Schuberg Philis BV.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::Helper
def load_current_resource
require 'win32ole'
fonts_dir = WIN32OLE.new("WScript.Shell").SpecialFolders("Fonts")
@current_resource = Chef::Resource::WindowsFont.new(@new_resource.name)
@current_resource.file(win_friendly_path(::File.join(fonts_dir, @new_resource.file)))
@current_resource
end
# Check to see if the font is installed
#
# === Returns
# <true>:: If the font is installed
# <false>:: If the font is not instaled
def font_exists?
::File.exists?(@current_resource.file)
end
def get_cookbook_font
r = Chef::Resource::CookbookFile.new(@new_resource.file, run_context)
r.path(win_friendly_path(::File.join(ENV['TEMP'], @new_resource.file)))
r.cookbook(cookbook_name.to_s)
r.run_action(:create)
end
def del_cookbook_font
r = Chef::Resource::File.new(::File.join(ENV['TEMP'], @new_resource.file), run_context)
r.run_action(:delete)
end
def install_font
require 'win32ole'
fonts_dir = WIN32OLE.new("WScript.Shell").SpecialFolders("Fonts")
folder = WIN32OLE.new("Shell.Application").Namespace(fonts_dir)
folder.CopyHere(win_friendly_path(::File.join(ENV['TEMP'], @new_resource.file)))
Chef::Log.debug("Installing font: #{@new_resource.file}")
end
def action_install
unless font_exists?
get_cookbook_font
install_font
del_cookbook_font
new_resource.updated_by_last_action(true)
else
Chef::Log.debug("Not installing font: #{@new_resource.file}, font already installed.")
new_resource.updated_by_last_action(false)
end
end
#
# Author:: Sander Botman <sbotman@schubergphilis.com>
# Cookbook Name:: windows
# Provider:: font
#
# Copyright:: 2014, Schuberg Philis BV.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::Helper
def load_current_resource
require 'win32ole'
fonts_dir = WIN32OLE.new('WScript.Shell').SpecialFolders('Fonts')
@current_resource = Chef::Resource::WindowsFont.new(@new_resource.name)
@current_resource.file(win_friendly_path(::File.join(fonts_dir, @new_resource.file)))
@current_resource
end
# Check to see if the font is installed
#
# === Returns
# <true>:: If the font is installed
# <false>:: If the font is not instaled
def font_exists?
::File.exist?(@current_resource.file)
end
def get_cookbook_font
r = Chef::Resource::CookbookFile.new(@new_resource.file, run_context)
r.path(win_friendly_path(::File.join(ENV['TEMP'], @new_resource.file)))
r.cookbook(cookbook_name.to_s)
r.run_action(:create)
end
def del_cookbook_font
r = Chef::Resource::File.new(::File.join(ENV['TEMP'], @new_resource.file), run_context)
r.run_action(:delete)
end
def install_font
require 'win32ole'
fonts_dir = WIN32OLE.new('WScript.Shell').SpecialFolders('Fonts')
folder = WIN32OLE.new('Shell.Application').Namespace(fonts_dir)
folder.CopyHere(win_friendly_path(::File.join(ENV['TEMP'], @new_resource.file)))
Chef::Log.debug("Installing font: #{@new_resource.file}")
end
def action_install
unless font_exists?
get_cookbook_font
install_font
del_cookbook_font
new_resource.updated_by_last_action(true)
else
Chef::Log.debug("Not installing font: #{@new_resource.file}, font already installed.")
new_resource.updated_by_last_action(false)
end
end

View File

@@ -0,0 +1,91 @@
#
# Author:: Richard Lavey (richard.lavey@calastone.com)
# Cookbook Name:: windows
# Provider:: http_acl
#
# Copyright:: 2015, Calastone Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See https://msdn.microsoft.com/en-us/library/windows/desktop/cc307236%28v=vs.85%29.aspx for netsh info
include Chef::Mixin::ShellOut
include Windows::Helper
# Support whyrun
def whyrun_supported?
true
end
action :create do
fail 'No user property set' if @new_resource.user.nil? || @new_resource.user.empty?
if @current_resource.exists
needsChange = (@current_resource.user.casecmp(@new_resource.user) != 0)
if needsChange
converge_by("Changing #{@current_resource.url}") do
deleteAcl
setAcl
end
else
Chef::Log.debug("#{@current_resource.url} already set - nothing to do")
end
else
converge_by("Setting #{@current_resource.url}") do
setAcl
end
end
end
action :delete do
if @current_resource.exists
converge_by("Deleting #{@current_resource.url}") do
deleteAcl
end
else
Chef::Log.debug("#{@current_resource.url} does not exist - nothing to do")
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsHttpAcl.new(@new_resource.name)
@current_resource.url(@new_resource.url)
@command = locate_sysnative_cmd('netsh.exe')
getCurrentAcl
end
private
def getCurrentAcl
cmd = shell_out!("#{@command} http show urlacl url=#{@current_resource.url}")
Chef::Log.debug "netsh reports: #{cmd.stdout}"
m = cmd.stdout.scan(/User:\s*(\S+)/)
if m.length == 0
@current_resource.exists = false
else
@current_resource.user(m[0][0])
@current_resource.exists = true
end
end
def setAcl
shell_out!("#{@command} http add urlacl url=#{@new_resource.url} user=\"#{@new_resource.user}\"")
end
def deleteAcl
shell_out!("#{@command} http delete urlacl url=#{@new_resource.url}")
end

View File

@@ -1,153 +1,149 @@
#
# Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: pagefile
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Chef::Mixin::ShellOut
include Windows::Helper
action :set do
pagefile = @new_resource.name
initial_size = @new_resource.initial_size
maximum_size = @new_resource.maximum_size
system_managed = @new_resource.system_managed
automatic_managed = @new_resource.automatic_managed
updated = false
if automatic_managed
unless automatic_managed?
set_automatic_managed
updated = true
end
else
if automatic_managed?
unset_automatic_managed
updated = true
end
# Check that the resource is not just trying to unset automatic managed, if it is do nothing more
if (initial_size && maximum_size) || system_managed
unless exists?(pagefile)
create(pagefile)
end
if system_managed
unless max_and_min_set?(pagefile, 0, 0)
set_system_managed(pagefile)
updated = true
end
else
unless max_and_min_set?(pagefile, initial_size, maximum_size)
set_custom_size(pagefile, initial_size, maximum_size)
updated = true
end
end
end
end
new_resource.updated_by_last_action(updated)
end
action :delete do
pagefile = @new_resource.name
updated = false
if exists?(pagefile)
delete(pagefile)
updated = true
end
new_resource.updated_by_last_action(updated)
end
private
def exists?(pagefile)
@exists ||= begin
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", {:returns => [0]})
cmd.stderr.empty? && (cmd.stdout =~ /SettingID=#{get_setting_id(pagefile)}/i)
end
end
def max_and_min_set?(pagefile, min, max)
@max_and_min_set ||= begin
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", {:returns => [0]})
cmd.stderr.empty? && (cmd.stdout =~ /InitialSize=#{min}/i) && (cmd.stdout =~ /MaximumSize=#{max}/i)
end
end
def create(pagefile)
Chef::Log.debug("Creating pagefile #{pagefile}")
cmd = shell_out("#{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"")
check_for_errors(cmd.stderr)
end
def delete(pagefile)
Chef::Log.debug("Removing pagefile #{pagefile}")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete")
check_for_errors(cmd.stderr)
end
def automatic_managed?
@automatic_managed ||= begin
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" get AutomaticManagedPagefile /format:list")
cmd.stderr.empty? && (cmd.stdout =~ /AutomaticManagedPagefile=TRUE/i)
end
end
def set_automatic_managed
Chef::Log.debug("Setting pagefile to Automatic Managed")
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True")
check_for_errors(cmd.stderr)
end
def unset_automatic_managed
Chef::Log.debug("Setting pagefile to User Managed")
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False")
check_for_errors(cmd.stderr)
end
def set_custom_size(pagefile, min, max)
Chef::Log.debug("Setting #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=#{min},MaximumSize=#{max}", {:returns => [0]})
check_for_errors(cmd.stderr)
end
def set_system_managed(pagefile)
Chef::Log.debug("Setting #{pagefile} to System Managed")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0", {:returns => [0]})
check_for_errors(cmd.stderr)
end
def get_setting_id(pagefile)
pagefile = win_friendly_path(pagefile)
pagefile = pagefile.split("\\")
"#{pagefile[1]} @ #{pagefile[0]}"
end
def check_for_errors(stderr)
unless stderr.empty?
Chef::Log.fatal(stderr)
end
end
def wmic
@wmic ||= begin
locate_sysnative_cmd("wmic.exe")
end
end
#
# Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: pagefile
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Chef::Mixin::ShellOut
include Windows::Helper
action :set do
pagefile = @new_resource.name
initial_size = @new_resource.initial_size
maximum_size = @new_resource.maximum_size
system_managed = @new_resource.system_managed
automatic_managed = @new_resource.automatic_managed
updated = false
if automatic_managed
unless automatic_managed?
set_automatic_managed
updated = true
end
else
if automatic_managed?
unset_automatic_managed
updated = true
end
# Check that the resource is not just trying to unset automatic managed, if it is do nothing more
if (initial_size && maximum_size) || system_managed
create(pagefile) unless exists?(pagefile)
if system_managed
unless max_and_min_set?(pagefile, 0, 0)
set_system_managed(pagefile)
updated = true
end
else
unless max_and_min_set?(pagefile, initial_size, maximum_size)
set_custom_size(pagefile, initial_size, maximum_size)
updated = true
end
end
end
end
new_resource.updated_by_last_action(updated)
end
action :delete do
pagefile = @new_resource.name
updated = false
if exists?(pagefile)
delete(pagefile)
updated = true
end
new_resource.updated_by_last_action(updated)
end
private
def exists?(pagefile)
@exists ||= begin
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", returns: [0])
cmd.stderr.empty? && (cmd.stdout =~ /SettingID=#{get_setting_id(pagefile)}/i)
end
end
def max_and_min_set?(pagefile, min, max)
@max_and_min_set ||= begin
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list", returns: [0])
cmd.stderr.empty? && (cmd.stdout =~ /InitialSize=#{min}/i) && (cmd.stdout =~ /MaximumSize=#{max}/i)
end
end
def create(pagefile)
Chef::Log.debug("Creating pagefile #{pagefile}")
cmd = shell_out("#{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"")
check_for_errors(cmd.stderr)
end
def delete(pagefile)
Chef::Log.debug("Removing pagefile #{pagefile}")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete")
check_for_errors(cmd.stderr)
end
def automatic_managed?
@automatic_managed ||= begin
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" get AutomaticManagedPagefile /format:list")
cmd.stderr.empty? && (cmd.stdout =~ /AutomaticManagedPagefile=TRUE/i)
end
end
def set_automatic_managed
Chef::Log.debug('Setting pagefile to Automatic Managed')
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True")
check_for_errors(cmd.stderr)
end
def unset_automatic_managed
Chef::Log.debug('Setting pagefile to User Managed')
cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False")
check_for_errors(cmd.stderr)
end
def set_custom_size(pagefile, min, max)
Chef::Log.debug("Setting #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=#{min},MaximumSize=#{max}", returns: [0])
check_for_errors(cmd.stderr)
end
def set_system_managed(pagefile)
Chef::Log.debug("Setting #{pagefile} to System Managed")
cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0", returns: [0])
check_for_errors(cmd.stderr)
end
def get_setting_id(pagefile)
pagefile = win_friendly_path(pagefile)
pagefile = pagefile.split('\\')
"#{pagefile[1]} @ #{pagefile[0]}"
end
def check_for_errors(stderr)
Chef::Log.fatal(stderr) unless stderr.empty?
end
def wmic
@wmic ||= begin
locate_sysnative_cmd('wmic.exe')
end
end

View File

@@ -1,52 +1,52 @@
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: path
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
include Windows::Helper
action :add do
env "path" do
action :modify
delim ::File::PATH_SEPARATOR
value new_resource.path
notifies :run, "ruby_block[fix ruby ENV['PATH']]", :immediately
end
# The windows Env provider does not correctly expand variables in
# the PATH environment variable. Ruby expects these to be expanded.
# This is a temporary fix for that.
#
# Follow at https://github.com/chef/chef/pull/1876
#
ruby_block "fix ruby ENV['PATH']" do
block do
ENV['PATH'] = expand_env_vars(ENV['PATH'])
end
action :nothing
end
end
action :remove do
env "path" do
action :delete
delim ::File::PATH_SEPARATOR
value new_resource.path
end
end
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: path
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
include Windows::Helper
action :add do
env 'path' do
action :modify
delim ::File::PATH_SEPARATOR
value new_resource.path
notifies :run, "ruby_block[fix ruby ENV['PATH']]", :immediately
end
# The windows Env provider does not correctly expand variables in
# the PATH environment variable. Ruby expects these to be expanded.
# This is a temporary fix for that.
#
# Follow at https://github.com/chef/chef/pull/1876
#
ruby_block "fix ruby ENV['PATH']" do
block do
ENV['PATH'] = expand_env_vars(ENV['PATH'])
end
action :nothing
end
end
action :remove do
env 'path' do
action :delete
delim ::File::PATH_SEPARATOR
value new_resource.path
end
end

View File

@@ -1,101 +1,99 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: printer
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
# Support whyrun
def whyrun_supported?
true
end
action :create do
if @current_resource.exists
Chef::Log.info "#{ @new_resource } already exists - nothing to do."
else
converge_by("Create #{ @new_resource }") do
create_printer
end
end
end
action :delete do
if @current_resource.exists
converge_by("Delete #{ @new_resource }") do
delete_printer
end
else
Chef::Log.info "#{ @current_resource } doesn't exist - can't delete."
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsPrinter.new(@new_resource.name)
@current_resource.name(@new_resource.name)
if printer_exists?(@current_resource.name)
# TODO: Set @current_resource printer properties from registry
@current_resource.exists = true
end
end
private
PRINTERS_REG_KEY = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\\'.freeze unless defined?(PRINTERS_REG_KEY)
def printer_exists?(name)
printer_reg_key = PRINTERS_REG_KEY + name
Chef::Log.debug "Checking to see if this reg key exists: '#{ printer_reg_key }'"
Registry.key_exists?(printer_reg_key)
end
def create_printer
# Create the printer port first
windows_printer_port new_resource.ipv4_address do
end
port_name = "IP_#{ new_resource.ipv4_address }"
powershell_script "Creating printer: #{ new_resource.name }" do
code <<-EOH
Set-WmiInstance -class Win32_Printer `
-EnableAllPrivileges `
-Argument @{ DeviceID = "#{ new_resource.device_id }";
Comment = "#{ new_resource.comment }";
Default = "$#{ new_resource.default }";
DriverName = "#{ new_resource.driver_name }";
Location = "#{ new_resource.location }";
PortName = "#{ port_name }";
Shared = "$#{ new_resource.shared }";
ShareName = "#{ new_resource.share_name }";
}
EOH
end
end
def delete_printer
powershell_script "Deleting printer: #{ new_resource.name }" do
code <<-EOH
$printer = Get-WMIObject -class Win32_Printer -EnableAllPrivileges -Filter "name = '#{ new_resource.name }'"
$printer.Delete()
EOH
end
end
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: printer
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
# Support whyrun
def whyrun_supported?
true
end
action :create do
if @current_resource.exists
Chef::Log.info "#{@new_resource} already exists - nothing to do."
else
converge_by("Create #{@new_resource}") do
create_printer
end
end
end
action :delete do
if @current_resource.exists
converge_by("Delete #{@new_resource}") do
delete_printer
end
else
Chef::Log.info "#{@current_resource} doesn't exist - can't delete."
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsPrinter.new(@new_resource.name)
@current_resource.name(@new_resource.name)
if printer_exists?(@current_resource.name)
# TODO: Set @current_resource printer properties from registry
@current_resource.exists = true
end
end
private
PRINTERS_REG_KEY = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\\'.freeze unless defined?(PRINTERS_REG_KEY)
def printer_exists?(name)
printer_reg_key = PRINTERS_REG_KEY + name
Chef::Log.debug "Checking to see if this reg key exists: '#{printer_reg_key}'"
Registry.key_exists?(printer_reg_key)
end
def create_printer
# Create the printer port first
windows_printer_port new_resource.ipv4_address do
end
port_name = "IP_#{new_resource.ipv4_address}"
powershell_script "Creating printer: #{new_resource.name}" do
code <<-EOH
Set-WmiInstance -class Win32_Printer `
-EnableAllPrivileges `
-Argument @{ DeviceID = "#{new_resource.device_id}";
Comment = "#{new_resource.comment}";
Default = "$#{new_resource.default}";
DriverName = "#{new_resource.driver_name}";
Location = "#{new_resource.location}";
PortName = "#{port_name}";
Shared = "$#{new_resource.shared}";
ShareName = "#{new_resource.share_name}";
}
EOH
end
end
def delete_printer
powershell_script "Deleting printer: #{new_resource.name}" do
code <<-EOH
$printer = Get-WMIObject -class Win32_Printer -EnableAllPrivileges -Filter "name = '#{new_resource.name}'"
$printer.Delete()
EOH
end
end

View File

@@ -1,103 +1,99 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: printer_port
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
# Support whyrun
def whyrun_supported?
true
end
action :create do
if @current_resource.exists
Chef::Log.info "#{ @new_resource } already exists - nothing to do."
else
converge_by("Create #{ @new_resource }") do
create_printer_port
end
end
end
action :delete do
if @current_resource.exists
converge_by("Delete #{ @new_resource }") do
delete_printer_port
end
else
Chef::Log.info "#{ @current_resource } doesn't exist - can't delete."
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsPrinterPort.new(@new_resource.name)
@current_resource.name(@new_resource.name)
@current_resource.ipv4_address(@new_resource.ipv4_address)
@current_resource.port_name(@new_resource.port_name || "IP_#{ @new_resource.ipv4_address }")
if port_exists?(@current_resource.port_name)
# TODO: Set @current_resource port properties from registry
@current_resource.exists = true
end
end
private
PORTS_REG_KEY = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\\'.freeze unless defined?(PORTS_REG_KEY)
def port_exists?(name)
port_reg_key = PORTS_REG_KEY + name
Chef::Log.debug "Checking to see if this reg key exists: '#{ port_reg_key }'"
Registry.key_exists?(port_reg_key)
end
def create_printer_port
port_name = new_resource.port_name || "IP_#{ new_resource.ipv4_address }"
# create the printer port using PowerShell
powershell_script "Creating printer port #{ new_resource.port_name }" do
code <<-EOH
Set-WmiInstance -class Win32_TCPIPPrinterPort `
-EnableAllPrivileges `
-Argument @{ HostAddress = "#{ new_resource.ipv4_address }";
Name = "#{ port_name }";
Description = "#{ new_resource.port_description }";
PortNumber = "#{ new_resource.port_number }";
Protocol = "#{ new_resource.port_protocol }";
SNMPEnabled = "$#{ new_resource.snmp_enabled }";
}
EOH
end
end
def delete_printer_port
port_name = new_resource.port_name || "IP_#{ new_resource.ipv4_address }"
powershell_script "Deleting printer port: #{ new_resource.port_name }" do
code <<-EOH
$port = Get-WMIObject -class Win32_TCPIPPrinterPort -EnableAllPrivileges -Filter "name = '#{ port_name }'"
$port.Delete()
EOH
end
end
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Provider:: printer_port
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use_inline_resources if defined?(use_inline_resources)
# Support whyrun
def whyrun_supported?
true
end
action :create do
if @current_resource.exists
Chef::Log.info "#{@new_resource} already exists - nothing to do."
else
converge_by("Create #{@new_resource}") do
create_printer_port
end
end
end
action :delete do
if @current_resource.exists
converge_by("Delete #{@new_resource}") do
delete_printer_port
end
else
Chef::Log.info "#{@current_resource} doesn't exist - can't delete."
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsPrinterPort.new(@new_resource.name)
@current_resource.name(@new_resource.name)
@current_resource.ipv4_address(@new_resource.ipv4_address)
@current_resource.port_name(@new_resource.port_name || "IP_#{@new_resource.ipv4_address}")
if port_exists?(@current_resource.port_name)
# TODO: Set @current_resource port properties from registry
@current_resource.exists = true
end
end
private
PORTS_REG_KEY = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\\'.freeze unless defined?(PORTS_REG_KEY)
def port_exists?(name)
port_reg_key = PORTS_REG_KEY + name
Chef::Log.debug "Checking to see if this reg key exists: '#{port_reg_key}'"
Registry.key_exists?(port_reg_key)
end
def create_printer_port
port_name = new_resource.port_name || "IP_#{new_resource.ipv4_address}"
# create the printer port using PowerShell
powershell_script "Creating printer port #{new_resource.port_name}" do
code <<-EOH
Set-WmiInstance -class Win32_TCPIPPrinterPort `
-EnableAllPrivileges `
-Argument @{ HostAddress = "#{new_resource.ipv4_address}";
Name = "#{port_name}";
Description = "#{new_resource.port_description}";
PortNumber = "#{new_resource.port_number}";
Protocol = "#{new_resource.port_protocol}";
SNMPEnabled = "$#{new_resource.snmp_enabled}";
}
EOH
end
end
def delete_printer_port
port_name = new_resource.port_name || "IP_#{new_resource.ipv4_address}"
powershell_script "Deleting printer port: #{new_resource.port_name}" do
code <<-EOH
$port = Get-WMIObject -class Win32_TCPIPPrinterPort -EnableAllPrivileges -Filter "name = '#{port_name}'"
$port.Delete()
EOH
end
end

View File

@@ -1,33 +1,33 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: reboot
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
action :request do
node.run_state[:reboot_requested] = true
node.run_state[:reboot_timeout] = @new_resource.timeout
node.run_state[:reboot_reason] = @new_resource.reason
new_resource.updated_by_last_action(true)
end
action :cancel do
node.run_state.delete(:reboot_requested)
node.run_state.delete(:reboot_timeout)
node.run_state.delete(:reboot_reason)
new_resource.updated_by_last_action(true)
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: reboot
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
action :request do
node.run_state[:reboot_requested] = true
node.run_state[:reboot_timeout] = @new_resource.timeout
node.run_state[:reboot_reason] = @new_resource.reason
new_resource.updated_by_last_action(true)
end
action :cancel do
node.run_state.delete(:reboot_requested)
node.run_state.delete(:reboot_timeout)
node.run_state.delete(:reboot_reason)
new_resource.updated_by_last_action(true)
end

View File

@@ -1,75 +1,75 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Chef Software, Inc.
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::RegistryHelper
action :create do
updated = registry_update(:create)
new_resource.updated_by_last_action(updated)
end
action :modify do
updated = registry_update(:open)
new_resource.updated_by_last_action(updated)
end
action :force_modify do
require 'timeout'
Timeout.timeout(120) do
@new_resource.values.each do |value_name, value_data|
i = 1
until i > 5 do
desired_value_data = value_data
current_value_data = get_value(@new_resource.key_name.dup, value_name.dup)
if current_value_data.to_s == desired_value_data.to_s
Chef::Log.debug("#{@new_resource} value [#{value_name}] desired [#{desired_value_data}] data already set. Check #{i}/5.")
i+=1
else
Chef::Log.debug("#{@new_resource} value [#{value_name}] current [#{current_value_data}] data not equal to desired [#{desired_value_data}] data. Setting value and restarting check loop.")
begin
updated = registry_update(:open)
new_resource.updated_by_last_action(updated)
rescue Exception
updated = registry_update(:create)
new_resource.updated_by_last_action(updated)
end
i=0 # start count loop over
end
end
end
break
end
end
action :remove do
delete_value(@new_resource.key_name,@new_resource.values)
new_resource.updated_by_last_action(true)
end
private
def registry_update(mode)
Chef::Log.debug("Registry Mode (#{mode})")
updated = set_value(mode,@new_resource.key_name,@new_resource.values,@new_resource.type)
end
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Provider:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011-2015, Chef Software, Inc.
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::RegistryHelper
action :create do
updated = registry_update(:create)
new_resource.updated_by_last_action(updated)
end
action :modify do
updated = registry_update(:open)
new_resource.updated_by_last_action(updated)
end
action :force_modify do
require 'timeout'
Timeout.timeout(120) do
@new_resource.values.each do |value_name, value_data|
i = 1
until i > 5
desired_value_data = value_data
current_value_data = get_value(@new_resource.key_name.dup, value_name.dup)
if current_value_data.to_s == desired_value_data.to_s
Chef::Log.debug("#{@new_resource} value [#{value_name}] desired [#{desired_value_data}] data already set. Check #{i}/5.")
i += 1
else
Chef::Log.debug("#{@new_resource} value [#{value_name}] current [#{current_value_data}] data not equal to desired [#{desired_value_data}] data. Setting value and restarting check loop.")
begin
updated = registry_update(:open)
new_resource.updated_by_last_action(updated)
rescue Exception
updated = registry_update(:create)
new_resource.updated_by_last_action(updated)
end
i = 0 # start count loop over
end
end
end
break
end
end
action :remove do
delete_value(@new_resource.key_name, @new_resource.values)
new_resource.updated_by_last_action(true)
end
private
def registry_update(mode)
Chef::Log.debug("Registry Mode (#{mode})")
updated = set_value(mode, @new_resource.key_name, @new_resource.values, @new_resource.type)
end

View File

@@ -1,56 +1,58 @@
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Cookbook Name:: windows
# Provider:: shortcut
#
# Copyright:: 2010, VMware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
def load_current_resource
require 'win32ole'
@link = WIN32OLE.new("WScript.Shell").CreateShortcut(@new_resource.name)
@current_resource = Chef::Resource::WindowsShortcut.new(@new_resource.name)
@current_resource.name(@new_resource.name)
@current_resource.target(@link.TargetPath)
@current_resource.arguments(@link.Arguments)
@current_resource.description(@link.Description)
@current_resource.cwd(@link.WorkingDirectory)
end
# Check to see if the shorcut needs any changes
#
# === Returns
# <true>:: If a change is required
# <false>:: If the shorcuts are identical
def compare_shortcut
[:target, :arguments, :description, :cwd].any? do |attr|
!@new_resource.send(attr).nil? && @current_resource.send(attr) != @new_resource.send(attr)
end
end
def action_create
if compare_shortcut
@link.TargetPath = @new_resource.target if @new_resource.target != nil
@link.Arguments = @new_resource.arguments if @new_resource.arguments != nil
@link.Description = @new_resource.description if @new_resource.description != nil
@link.WorkingDirectory = @new_resource.cwd if @new_resource.cwd != nil
#ignoring: WindowStyle, Hotkey, IconLocation
@link.Save
Chef::Log.info("Added #{@new_resource} shortcut")
new_resource.updated_by_last_action(true)
end
end
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Cookbook Name:: windows
# Provider:: shortcut
#
# Copyright:: 2010, VMware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
def load_current_resource
require 'win32ole'
@link = WIN32OLE.new('WScript.Shell').CreateShortcut(@new_resource.name)
@current_resource = Chef::Resource::WindowsShortcut.new(@new_resource.name)
@current_resource.name(@new_resource.name)
@current_resource.target(@link.TargetPath)
@current_resource.arguments(@link.Arguments)
@current_resource.description(@link.Description)
@current_resource.cwd(@link.WorkingDirectory)
@current_resource.iconlocation(@link.IconLocation)
end
# Check to see if the shorcut needs any changes
#
# === Returns
# <true>:: If a change is required
# <false>:: If the shorcuts are identical
def compare_shortcut
[:target, :arguments, :description, :cwd, :iconlocation].any? do |attr|
!@new_resource.send(attr).nil? && @current_resource.send(attr) != @new_resource.send(attr)
end
end
def action_create
if compare_shortcut
@link.TargetPath = @new_resource.target unless @new_resource.target.nil?
@link.Arguments = @new_resource.arguments unless @new_resource.arguments.nil?
@link.Description = @new_resource.description unless @new_resource.description.nil?
@link.WorkingDirectory = @new_resource.cwd unless @new_resource.cwd.nil?
@link.IconLocation = @new_resource.iconlocation unless @new_resource.iconlocation.nil?
# ignoring: WindowStyle, Hotkey
@link.Save
Chef::Log.info("Added #{@new_resource} shortcut")
new_resource.updated_by_last_action(true)
end
end

View File

@@ -1,167 +1,236 @@
#
# Author:: Paul Mooring (<paul@chef.io>)
# Cookbook Name:: windows
# Provider:: task
#
# Copyright:: 2012, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut
action :create do
if @current_resource.exists
Chef::Log.info "#{@new_resource} task already exists - nothing to do"
else
if @new_resource.user and @new_resource.password.nil? then Chef::Log.debug "#{@new_resource} did not specify a password, creating task without a password" end
use_force = @new_resource.force ? '/F' : ''
cmd = "schtasks /Create #{use_force} /TN \"#{@new_resource.name}\" "
schedule = @new_resource.frequency == :on_logon ? "ONLOGON" : @new_resource.frequency
cmd += "/SC #{schedule} "
cmd += "/MO #{@new_resource.frequency_modifier} " if [:minute, :hourly, :daily, :weekly, :monthly].include?(@new_resource.frequency)
cmd += "/SD \"#{@new_resource.start_day}\" " unless @new_resource.start_day.nil?
cmd += "/ST \"#{@new_resource.start_time}\" " unless @new_resource.start_time.nil?
cmd += "/TR \"#{@new_resource.command}\" "
cmd += "/RU \"#{@new_resource.user}\" " if @new_resource.user
cmd += "/RP \"#{@new_resource.password}\" " if @new_resource.user and @new_resource.password
cmd += "/RL HIGHEST " if @new_resource.run_level == :highest
shell_out!(cmd, {:returns => [0]})
new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task created"
end
end
action :run do
if @current_resource.exists
if @current_resource.status == :running
Chef::Log.info "#{@new_resource} task is currently running, skipping run"
else
cmd = "schtasks /Run /TN \"#{@current_resource.name}\""
shell_out!(cmd, {:returns => [0]})
new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task ran"
end
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :change do
if @current_resource.exists
cmd = "schtasks /Change /TN \"#{@current_resource.name}\" "
cmd += "/TR \"#{@new_resource.command}\" " if @new_resource.command
if @new_resource.user && @new_resource.password
cmd += "/RU \"#{@new_resource.user}\" /RP \"#{@new_resource.password}\" "
elsif (@new_resource.user and !@new_resource.password) || (@new_resource.password and !@new_resource.user)
Chef::Log.fatal "#{@new_resource.name}: Can't specify user or password without both!"
end
shell_out!(cmd, {:returns => [0]})
new_resource.updated_by_last_action true
Chef::Log.info "Change #{@new_resource} task ran"
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :delete do
if @current_resource.exists
use_force = @new_resource.force ? '/F' : ''
cmd = "schtasks /Delete #{use_force} /TN \"#{@current_resource.name}\""
shell_out!(cmd, {:returns => [0]})
new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task deleted"
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :enable do
if @current_resource.exists
if @current_resource.enabled
Chef::Log.debug "#{@new_resource} already enabled - nothing to do"
else
cmd = "schtasks /Change /TN \"#{@current_resource.name}\" "
cmd += "/ENABLE"
shell_out!(cmd, {:returns => [0]})
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task enabled"
end
else
Chef::Log.fatal "#{@new_resource} task doesn't exist - nothing to do"
raise Errno::ENOENT, "#{@new_resource}: task does not exist, cannot enable"
end
end
action :disable do
if @current_resource.exists
if @current_resource.enabled
cmd = "schtasks /Change /TN \"#{@current_resource.name}\" "
cmd += "/DISABLE"
shell_out!(cmd, {:returns => [0]})
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task disabled"
else
Chef::Log.debug "#{@new_resource} already disabled - nothing to do"
end
else
Chef::Log.debug "#{@new_resource} task doesn't exist - nothing to do"
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsTask.new(@new_resource.name)
@current_resource.name(@new_resource.name)
task_hash = load_task_hash(@current_resource.name)
if task_hash[:TaskName] == '\\' + @new_resource.name
@current_resource.exists = true
if task_hash[:Status] == "Running"
@current_resource.status = :running
end
if task_hash[:ScheduledTaskState] == "Enabled"
@current_resource.enabled = true
end
@current_resource.cwd(task_hash[:Folder])
@current_resource.command(task_hash[:TaskToRun])
@current_resource.user(task_hash[:RunAsUser])
end if task_hash.respond_to? :[]
end
private
def load_task_hash(task_name)
Chef::Log.debug "looking for existing tasks"
# we use shell_out here instead of shell_out! because a failure implies that the task does not exist
output = shell_out("schtasks /Query /FO LIST /V /TN \"#{task_name}\"").stdout
if output.empty?
task = false
else
task = Hash.new
output.split("\n").map! do |line|
line.split(":", 2).map! do |field|
field.strip
end
end.each do |field|
if field.kind_of? Array and field[0].respond_to? :to_sym
task[field[0].gsub(/\s+/,"").to_sym] = field[1]
end
end
end
task
end
#
# Author:: Paul Mooring (<paul@chef.io>)
# Cookbook Name:: windows
# Provider:: task
#
# Copyright:: 2012-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut
use_inline_resources
action :create do
if @current_resource.exists && (!(task_need_update? || @new_resource.force))
Chef::Log.info "#{@new_resource} task already exists - nothing to do"
else
validate_user_and_password
validate_interactive_setting
validate_create_day
schedule = @new_resource.frequency == :on_logon ? 'ONLOGON' : @new_resource.frequency
frequency_modifier_allowed = [:minute, :hourly, :daily, :weekly, :monthly]
options = {}
options['F'] = '' if @new_resource.force || task_need_update?
options['SC'] = schedule
options['MO'] = @new_resource.frequency_modifier if frequency_modifier_allowed.include?(@new_resource.frequency)
options['SD'] = @new_resource.start_day unless @new_resource.start_day.nil?
options['ST'] = @new_resource.start_time unless @new_resource.start_time.nil?
options['TR'] = "\"#{@new_resource.command}\" "
options['RU'] = @new_resource.user
options['RP'] = @new_resource.password if use_password?
options['RL'] = 'HIGHEST' if @new_resource.run_level == :highest
options['IT'] = '' if @new_resource.interactive_enabled
options['D'] = @new_resource.day if @new_resource.day
run_schtasks 'CREATE', options
new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task created"
end
end
action :run do
if @current_resource.exists
if @current_resource.status == :running
Chef::Log.info "#{@new_resource} task is currently running, skipping run"
else
run_schtasks 'RUN'
new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task ran"
end
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :change do
if @current_resource.exists
validate_user_and_password
validate_interactive_setting
options = {}
options['TR'] = "\"#{@new_resource.command}\" " if @new_resource.command
options['RU'] = @new_resource.user if @new_resource.user
options['RP'] = @new_resource.password if @new_resource.password
options['SD'] = @new_resource.start_day unless @new_resource.start_day.nil?
options['ST'] = @new_resource.start_time unless @new_resource.start_time.nil?
options['IT'] = '' if @new_resource.interactive_enabled
run_schtasks 'CHANGE', options
new_resource.updated_by_last_action true
Chef::Log.info "Change #{@new_resource} task ran"
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :delete do
if @current_resource.exists
# always need to force deletion
run_schtasks 'DELETE', 'F' => ''
new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task deleted"
else
Chef::Log.debug "#{@new_resource} task doesn't exists - nothing to do"
end
end
action :end do
if @current_resource.exists
if @current_resource.status != :running
Chef::Log.debug "#{@new_resource} is not running - nothing to do"
else
run_schtasks 'END'
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task ended"
end
else
Chef::Log.fatal "#{@new_resource} task doesn't exist - nothing to do"
fail Errno::ENOENT, "#{@new_resource}: task does not exist, cannot end"
end
end
action :enable do
if @current_resource.exists
if @current_resource.enabled
Chef::Log.debug "#{@new_resource} already enabled - nothing to do"
else
run_schtasks 'CHANGE', 'ENABLE' => ''
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task enabled"
end
else
Chef::Log.fatal "#{@new_resource} task doesn't exist - nothing to do"
fail Errno::ENOENT, "#{@new_resource}: task does not exist, cannot enable"
end
end
action :disable do
if @current_resource.exists
if @current_resource.enabled
run_schtasks 'CHANGE', 'DISABLE' => ''
@new_resource.updated_by_last_action true
Chef::Log.info "#{@new_resource} task disabled"
else
Chef::Log.debug "#{@new_resource} already disabled - nothing to do"
end
else
Chef::Log.debug "#{@new_resource} task doesn't exist - nothing to do"
end
end
def load_current_resource
@current_resource = Chef::Resource::WindowsTask.new(@new_resource.name)
@current_resource.task_name(@new_resource.task_name)
pathed_task_name = @new_resource.task_name[0, 1] == '\\' ? @new_resource.task_name : @new_resource.task_name.prepend('\\')
task_hash = load_task_hash(@current_resource.task_name)
if task_hash[:TaskName] == pathed_task_name
@current_resource.exists = true
@current_resource.status = :running if task_hash[:Status] == 'Running'
if task_hash[:ScheduledTaskState] == 'Enabled'
@current_resource.enabled = true
end
@current_resource.cwd(task_hash[:Folder])
@current_resource.command(task_hash[:TaskToRun])
@current_resource.user(task_hash[:RunAsUser])
end if task_hash.respond_to? :[]
end
private
def run_schtasks(task_action, options = {})
cmd = "schtasks /#{task_action} /TN \"#{@new_resource.task_name}\" "
options.keys.each do |option|
cmd += "/#{option} #{options[option]} "
end
Chef::Log.debug('running: ')
Chef::Log.debug(" #{cmd}")
shell_out!(cmd, returns: [0])
end
def task_need_update?
# gsub needed as schtasks converts single quotes to double quotes on creation
@current_resource.command != @new_resource.command.tr("'", "\"") ||
@current_resource.user != @new_resource.user
end
def load_task_hash(task_name)
Chef::Log.debug 'looking for existing tasks'
# we use shell_out here instead of shell_out! because a failure implies that the task does not exist
output = shell_out("schtasks /Query /FO LIST /V /TN \"#{task_name}\"").stdout
if output.empty?
task = false
else
task = {}
output.split("\n").map! do |line|
line.split(':', 2).map!(&:strip)
end.each do |field|
if field.is_a?(Array) && field[0].respond_to?(:to_sym)
task[field[0].gsub(/\s+/, '').to_sym] = field[1]
end
end
end
task
end
SYSTEM_USERS = ['NT AUTHORITY\SYSTEM', 'SYSTEM', 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE']
def validate_user_and_password
if @new_resource.user && use_password?
if @new_resource.password.nil?
Chef::Log.fatal "#{@new_resource.task_name}: Can't specify a non-system user without a password!"
end
end
end
def validate_interactive_setting
if @new_resource.interactive_enabled && @new_resource.password.nil?
Chef::Log.fatal "#{new_resource} did not provide a password when attempting to set interactive/non-interactive."
end
end
def validate_create_day
return unless @new_resource.day
unless [:weekly, :monthly].include?(@new_resource.frequency)
fail 'day attribute is only valid for tasks that run weekly or monthly'
end
if @new_resource.day.is_a? String
days = @new_resource.day.split(',')
days.each do |day|
unless ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun', '*'].include?(day.strip.downcase)
fail 'day attribute invalid. Only valid values are: MON, TUE, WED, THU, FRI, SAT, SUN and *. Multiple values must be separated by a comma.'
end
end
end
end
def use_password?
@use_password ||= !SYSTEM_USERS.include?(@new_resource.user.upcase)
end

View File

@@ -1,93 +1,90 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: zipfile
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::Helper
require 'find'
action :unzip do
ensure_rubyzip_gem_installed
Chef::Log.debug("unzip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})")
Zip::File.open(cached_file(@new_resource.source, @new_resource.checksum)) do |zip|
zip.each do |entry|
path = ::File.join(@new_resource.path, entry.name)
FileUtils.mkdir_p(::File.dirname(path))
if @new_resource.overwrite && ::File.exists?(path) && !::File.directory?(path)
FileUtils.rm(path)
end
zip.extract(entry, path)
end
end
new_resource.updated_by_last_action(true)
end
action :zip do
ensure_rubyzip_gem_installed
# sanitize paths for windows.
@new_resource.source.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
@new_resource.path.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
Chef::Log.debug("zip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})")
if @new_resource.overwrite == false && ::File.exists?(@new_resource.path)
Chef::Log.info("file #{@new_resource.path} already exists and overwrite is set to false, exiting")
else
# delete the archive if it already exists, because we are recreating it.
if ::File.exists?(@new_resource.path)
::File.unlink(@new_resource.path)
end
# only supporting compression of a single directory (recursively).
if ::File.directory?(@new_resource.source)
z = Zip::File.new(@new_resource.path, true)
unless @new_resource.source =~ /::File::ALT_SEPARATOR$/
@new_resource.source << ::File::ALT_SEPARATOR
end
Find.find(@new_resource.source) do |f|
f.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
# don't add root directory to the zipfile.
next if f == @new_resource.source
# strip the root directory from the filename before adding it to the zipfile.
zip_fname = f.sub(@new_resource.source, '')
Chef::Log.debug("adding #{zip_fname} to archive, sourcefile is: #{f}")
z.add(zip_fname, f)
end
z.close
new_resource.updated_by_last_action(true)
else
Chef::Log.info("Single directory must be specified for compression, and #{@new_resource.source} does not meet that criteria.")
end
end
end
private
def ensure_rubyzip_gem_installed
begin
require 'zip'
rescue LoadError
Chef::Log.info("Missing gem 'rubyzip'...installing now.")
chef_gem "rubyzip" do
version node['windows']['rubyzipversion']
action :install
end
require 'zip'
end
end
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Provider:: zipfile
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::Helper
require 'find'
action :unzip do
ensure_rubyzip_gem_installed
Chef::Log.debug("unzip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})")
Zip::File.open(cached_file(@new_resource.source, @new_resource.checksum)) do |zip|
zip.each do |entry|
path = ::File.join(@new_resource.path, entry.name)
FileUtils.mkdir_p(::File.dirname(path))
if @new_resource.overwrite && ::File.exist?(path) && !::File.directory?(path)
FileUtils.rm(path)
end
zip.extract(entry, path)
end
end
new_resource.updated_by_last_action(true)
end
action :zip do
ensure_rubyzip_gem_installed
# sanitize paths for windows.
@new_resource.source.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
@new_resource.path.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
Chef::Log.debug("zip #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})")
if @new_resource.overwrite == false && ::File.exist?(@new_resource.path)
Chef::Log.info("file #{@new_resource.path} already exists and overwrite is set to false, exiting")
else
# delete the archive if it already exists, because we are recreating it.
::File.unlink(@new_resource.path) if ::File.exist?(@new_resource.path)
# only supporting compression of a single directory (recursively).
if ::File.directory?(@new_resource.source)
z = Zip::File.new(@new_resource.path, true)
unless @new_resource.source =~ /::File::ALT_SEPARATOR$/
@new_resource.source << ::File::ALT_SEPARATOR
end
Find.find(@new_resource.source) do |f|
f.downcase.gsub!(::File::SEPARATOR, ::File::ALT_SEPARATOR)
# don't add root directory to the zipfile.
next if f == @new_resource.source
# strip the root directory from the filename before adding it to the zipfile.
zip_fname = f.sub(@new_resource.source, '')
Chef::Log.debug("adding #{zip_fname} to archive, sourcefile is: #{f}")
z.add(zip_fname, f)
end
z.close
new_resource.updated_by_last_action(true)
else
Chef::Log.info("Single directory must be specified for compression, and #{@new_resource.source} does not meet that criteria.")
end
end
end
private
def ensure_rubyzip_gem_installed
require 'zip'
rescue LoadError
Chef::Log.info("Missing gem 'rubyzip'...installing now.")
chef_gem 'rubyzip' do
version node['windows']['rubyzipversion']
action :install
end
require 'zip'
end

View File

@@ -1,34 +1,34 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Recipe:: default
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# gems with precompiled binaries
%w{ win32-api win32-service }.each do |win_gem|
chef_gem win_gem do
options '--platform=mswin32'
action :install
end
end
# the rest
%w{ windows-api windows-pr win32-dir win32-event win32-mutex }.each do |win_gem|
chef_gem win_gem do
action :install
end
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Recipe:: default
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# gems with precompiled binaries
%w( win32-api win32-service ).each do |win_gem|
chef_gem win_gem do
options '--platform=mswin32'
action :install
end
end
# the rest
%w( windows-api windows-pr win32-dir win32-event win32-mutex ).each do |win_gem|
chef_gem win_gem do
action :install
end
end

View File

@@ -1,32 +1,32 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Recipe:: restart_handler
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
remote_directory node['chef_handler']['handler_path'] do
source 'handlers'
recursive true
action :create
end
chef_handler 'WindowsRebootHandler' do
source "#{node['chef_handler']['handler_path']}/windows_reboot_handler.rb"
arguments node['windows']['allow_pending_reboots']
supports :report => true, :exception => node['windows']['allow_reboot_on_failure']
action :enable
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Recipe:: restart_handler
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
remote_directory node['chef_handler']['handler_path'] do
source 'handlers'
recursive true
action :create
end
chef_handler 'WindowsRebootHandler' do
source "#{node['chef_handler']['handler_path']}/windows_reboot_handler.rb"
arguments node['windows']['allow_pending_reboots']
supports report: true, exception: node['windows']['allow_reboot_on_failure']
action :enable
end

View File

@@ -1,30 +1,30 @@
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Resource:: auto_run
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
def initialize(name,run_context=nil)
super
@action = :create
end
actions :create, :remove
attribute :program, :kind_of => String
attribute :name, :kind_of => String, :name_attribute => true
attribute :args, :kind_of => String, :default => ''
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Resource:: auto_run
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
def initialize(name, run_context = nil)
super
@action = :create
end
actions :create, :remove
attribute :program, kind_of: String
attribute :name, kind_of: String, name_attribute: true
attribute :args, kind_of: String, default: ''

View File

@@ -1,36 +1,41 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: batch
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :run
attribute :command, :kind_of => String, :name_attribute => true
attribute :cwd, :kind_of => String, :default => nil
attribute :code, :kind_of => String, :default => nil
attribute :user, :kind_of => [ String, Integer ], :default => nil
attribute :group, :kind_of => [ String, Integer ], :default => nil
attribute :creates, :kind_of => [ String ], :default => nil
attribute :flags, :kind_of => [ String ], :default => nil
attribute :returns, :kind_of => [Integer, Array], :default => 0
def initialize(name, run_context=nil)
super
@action = :run
@command = name
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: batch
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :run
attribute :command, kind_of: String, name_attribute: true
attribute :cwd, kind_of: String, default: nil
attribute :code, kind_of: String, default: nil
attribute :user, kind_of: [String, Integer], default: nil
attribute :group, kind_of: [String, Integer], default: nil
attribute :creates, kind_of: [String], default: nil
attribute :flags, kind_of: [String], default: nil
attribute :returns, kind_of: [Integer, Array], default: 0
def initialize(name, run_context = nil)
super
@action = :run
@command = name
Chef::Log.warn <<-EOF
Please use the batch resource in Chef Client 11 and 12.
windows_batch will be removed in the next major version release
of the Windows cookbook.
EOF
end

View File

@@ -0,0 +1,28 @@
#
# Author:: Richard Lavey (richard.lavey@calastone.com)
# Cookbook Name:: windows
# Resource:: certificate
#
# Copyright:: 2015, Calastone Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :create, :delete, :acl_add
default_action :create
attribute :source, kind_of: String, name_attribute: true, required: true
attribute :pfx_password, kind_of: String
attribute :private_key_acl, kind_of: Array
attribute :store_name, kind_of: String, default: 'MY', regex: /^(?:MY|CA|ROOT)$/
attribute :user_store, kind_of: [TrueClass, FalseClass], default: false

View File

@@ -0,0 +1,31 @@
#
# Author:: Richard Lavey (richard.lavey@calastone.com)
# Cookbook Name:: windows
# Resource:: certificate_binding
#
# Copyright:: 2015, Calastone Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :create, :delete
default_action :create
attribute :cert_name, kind_of: String, name_attribute: true, required: true
attribute :name_kind, kind_of: Symbol, equal_to: [:hash, :subject], default: :subject
attribute :address, kind_of: String, default: '0.0.0.0'
attribute :port, kind_of: Integer, default: 443
attribute :app_id, kind_of: String, default: '{4dc3e181-e14b-4a21-b022-59fc669b0914}'
attribute :store_name, kind_of: String, default: 'MY', regex: /^(?:MY|CA|ROOT)$/
attr_accessor :exists

View File

@@ -1,44 +1,47 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: feature
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::Helper
actions :install, :remove, :delete
attribute :feature_name, :kind_of => String, :name_attribute => true
attribute :source, :kind_of => String
attribute :all, :kind_of => [ TrueClass, FalseClass ], :default => false
def initialize(name, run_context=nil)
super
@action = :install
@provider = lookup_provider_constant(locate_default_provider)
end
private
def locate_default_provider
if node['windows'].attribute?(:feature_provider)
"windows_feature_#{node['windows']['feature_provider']}"
elsif ::File.exists?(locate_sysnative_cmd('dism.exe'))
:windows_feature_dism
elsif ::File.exists?(locate_sysnative_cmd('servermanagercmd.exe'))
:windows_feature_servermanagercmd
end
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: feature
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include Windows::Helper
actions :install, :remove, :delete
attribute :feature_name, kind_of: String, name_attribute: true
attribute :source, kind_of: String
attribute :all, kind_of: [TrueClass, FalseClass], default: false
def initialize(name, run_context = nil)
super
@action = :install
@provider = lookup_provider_constant(locate_default_provider)
end
private
def locate_default_provider
if node['windows'].attribute?(:feature_provider)
"windows_feature_#{node['windows']['feature_provider']}"
elsif ::File.exist?(locate_sysnative_cmd('dism.exe'))
:windows_feature_dism
elsif ::File.exist?(locate_sysnative_cmd('servermanagercmd.exe'))
:windows_feature_servermanagercmd
else
:windows_feature_powershell
end
end

View File

@@ -1,25 +1,25 @@
#
# Author:: Sander Botman <sbotman@schubergphilis.com>
# Cookbook Name:: windows
# Resource:: font
#
# Copyright:: 2014, Schuberg Philis BV.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :install
default_action :install
attribute :file, :kind_of => String, :name_attribute => true
#
# Author:: Sander Botman <sbotman@schubergphilis.com>
# Cookbook Name:: windows
# Resource:: font
#
# Copyright:: 2014, Schuberg Philis BV.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :install
default_action :install
attribute :file, kind_of: String, name_attribute: true

View File

@@ -0,0 +1,27 @@
#
# Author:: Richard Lavey (richard.lavey@calastone.com)
# Cookbook Name:: windows
# Resource:: http_acl
#
# Copyright:: 2015, Calastone Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :create, :delete
default_action :create
attribute :url, kind_of: String, name_attribute: true, required: true
attribute :user, kind_of: String
attr_accessor :exists

View File

@@ -1,29 +1,29 @@
#
# Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: pagefile
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :set, :delete
attribute :name, :kind_of => String, :name_attribute => true
attribute :system_managed, :kind_of => [TrueClass, FalseClass]
attribute :automatic_managed, :kind_of => [TrueClass, FalseClass], :default => false
attribute :initial_size, :kind_of => Integer
attribute :maximum_size, :kind_of => Integer
default_action :set
#
# Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: pagefile
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :set, :delete
attribute :name, kind_of: String, name_attribute: true
attribute :system_managed, kind_of: [TrueClass, FalseClass]
attribute :automatic_managed, kind_of: [TrueClass, FalseClass], default: false
attribute :initial_size, kind_of: Integer
attribute :maximum_size, kind_of: Integer
default_action :set

View File

@@ -1,28 +1,28 @@
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Resource:: path
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
def initialize(name,run_context=nil)
super
@action = :add
end
actions :add, :remove
attribute :path, :kind_of => String, :name_attribute => true
#
# Author:: Paul Morton (<pmorton@biaprotect.com>)
# Cookbook Name:: windows
# Resource:: path
#
# Copyright:: 2011, Business Intelligence Associates, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
def initialize(name, run_context = nil)
super
@action = :add
end
actions :add, :remove
attribute :path, kind_of: String, name_attribute: true

View File

@@ -1,41 +1,41 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: printer
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See here for more info:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx
require 'resolv'
actions :create, :delete
default_action :create
attribute :device_id, :kind_of => String, :name_attribute => true,
:required => true
attribute :comment, :kind_of => String
attribute :default, :kind_of => [ TrueClass, FalseClass ], :default => false
attribute :driver_name, :kind_of => String, :required => true
attribute :location, :kind_of => String
attribute :shared, :kind_of => [ TrueClass, FalseClass ], :default => false
attribute :share_name, :kind_of => String
attribute :ipv4_address, :kind_of => String, :regex => Resolv::IPv4::Regex
attr_accessor :exists
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: printer
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See here for more info:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx
require 'resolv'
actions :create, :delete
default_action :create
attribute :device_id, kind_of: String, name_attribute: true,
required: true
attribute :comment, kind_of: String
attribute :default, kind_of: [TrueClass, FalseClass], default: false
attribute :driver_name, kind_of: String, required: true
attribute :location, kind_of: String
attribute :shared, kind_of: [TrueClass, FalseClass], default: false
attribute :share_name, kind_of: String
attribute :ipv4_address, kind_of: String, regex: Resolv::IPv4::Regex
attr_accessor :exists

View File

@@ -1,40 +1,40 @@
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: printer_port
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See here for more info:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx
require 'resolv'
actions :create, :delete
default_action :create
attribute :ipv4_address, :name_attribute => true, :kind_of => String,
:required => true, :regex => Resolv::IPv4::Regex
attribute :port_name , :kind_of => String
attribute :port_number , :kind_of => Fixnum, :default => 9100
attribute :port_description, :kind_of => String
attribute :snmp_enabled , :kind_of => [ TrueClass, FalseClass ],
:default => false
attribute :port_protocol, :kind_of => Fixnum, :default => 1, :equal_to => [1, 2]
attr_accessor :exists
#
# Author:: Doug Ireton (<doug.ireton@nordstrom.com>)
# Cookbook Name:: windows
# Resource:: printer_port
#
# Copyright:: 2012, Nordstrom, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# See here for more info:
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394492(v=vs.85).aspx
require 'resolv'
actions :create, :delete
default_action :create
attribute :ipv4_address, name_attribute: true, kind_of: String,
required: true, regex: Resolv::IPv4::Regex
attribute :port_name, kind_of: String
attribute :port_number, kind_of: Fixnum, default: 9100
attribute :port_description, kind_of: String
attribute :snmp_enabled, kind_of: [TrueClass, FalseClass],
default: false
attribute :port_protocol, kind_of: Fixnum, default: 1, equal_to: [1, 2]
attr_accessor :exists

View File

@@ -1,29 +1,34 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: reboot
#
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :request, :cancel
attribute :timeout, :kind_of => Integer, :name_attribute => true
attribute :reason, :kind_of => String, :default => ''
def initialize(name,run_context=nil)
super
@action = :request
end
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: reboot
#
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :request, :cancel
attribute :timeout, kind_of: Integer, name_attribute: true
attribute :reason, kind_of: String, default: 'Chef client run'
def initialize(name, run_context = nil)
super
@action = :request
Chef::Log.warn <<-EOF
The windows_reboot resource is deprecated. Please use the reboot resource in
Chef Client 12. windows_reboot will be removed in the next major version
release of the Windows cookbook.
EOF
end

View File

@@ -1,34 +1,38 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :create, :modify, :force_modify, :remove
attribute :key_name, :kind_of => String, :name_attribute => true
attribute :values, :kind_of => Hash
attribute :type, :kind_of => Symbol, :default => nil, :equal_to => [:binary, :string, :multi_string, :expand_string, :dword, :dword_big_endian, :qword]
def initialize(name, run_context=nil)
super
@action = :modify
@key_name = name
Chef::Log.warn("Please use the registry_key resource in Chef Client 11. The windows_registry LWRP is still supported for Chef Client 10, but is deprecated in future versions.")
end
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: registry
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :create, :modify, :force_modify, :remove
attribute :key_name, kind_of: String, name_attribute: true
attribute :values, kind_of: Hash
attribute :type, kind_of: Symbol, default: nil, equal_to: [:binary, :string, :multi_string, :expand_string, :dword, :dword_big_endian, :qword]
def initialize(name, run_context = nil)
super
@action = :modify
@key_name = name
Chef::Log.warn <<-EOF
Please use the registry_key resource in Chef Client 11 and 12.
windows_registry will be removed in the next major version release
of the Windows cookbook.
EOF
end

View File

@@ -1,35 +1,36 @@
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Cookbook Name:: windows
# Resource:: shortcut
#
# Copyright:: 2010, VMware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :create
default_action :create
attribute :name, :kind_of => String
attribute :target, :kind_of => String
attribute :arguments, :kind_of => String
attribute :description, :kind_of => String
attribute :cwd, :kind_of => String
# Covers 0.10.8 and earlier
def initialize(*args)
super
@action = :create
end
#
# Author:: Doug MacEachern <dougm@vmware.com>
# Cookbook Name:: windows
# Resource:: shortcut
#
# Copyright:: 2010, VMware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :create
default_action :create
attribute :name, kind_of: String
attribute :target, kind_of: String
attribute :arguments, kind_of: String
attribute :description, kind_of: String
attribute :cwd, kind_of: String
attribute :iconlocation, kind_of: String
# Covers 0.10.8 and earlier
def initialize(*args)
super
@action = :create
end

View File

@@ -1,50 +1,52 @@
#
# Author:: Paul Mooring (<paul@chef.io>)
# Cookbook Name:: windows
# Resource:: task
#
# Copyright:: 2012, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Passwords can't be loaded for existing tasks, making :modify both confusing
# and not very useful
actions :create, :delete, :run, :change, :enable, :disable
attribute :name, :kind_of => String, :name_attribute => true, :regex => [ /\A[^\\\/\:\*\?\<\>\|]+\z/ ]
attribute :command, :kind_of => String
attribute :cwd, :kind_of => String
attribute :user, :kind_of => String, :default => nil
attribute :password, :kind_of => String, :default => nil
attribute :run_level, :equal_to => [:highest, :limited], :default => :limited
attribute :force, :kind_of => [ TrueClass, FalseClass ], :default => false
attribute :frequency_modifier, :kind_of => Integer, :default => 1
attribute :frequency, :equal_to => [:minute,
:hourly,
:daily,
:weekly,
:monthly,
:once,
:on_logon,
:onstart,
:on_idle], :default => :hourly
attribute :start_day, :kind_of => String, :default => nil
attribute :start_time, :kind_of => String, :default => nil
attr_accessor :exists, :status, :enabled
def initialize(name, run_context=nil)
super
@action = :create
end
#
# Author:: Paul Mooring (<paul@chef.io>)
# Cookbook Name:: windows
# Resource:: task
#
# Copyright:: 2012-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Passwords can't be loaded for existing tasks, making :modify both confusing
# and not very useful
actions :create, :delete, :run, :end, :change, :enable, :disable
attribute :task_name, kind_of: String, name_attribute: true, regex: [/\A[^\/\:\*\?\<\>\|]+\z/]
attribute :command, kind_of: String
attribute :cwd, kind_of: String
attribute :user, kind_of: String, default: 'SYSTEM'
attribute :password, kind_of: String, default: nil
attribute :run_level, equal_to: [:highest, :limited], default: :limited
attribute :force, kind_of: [TrueClass, FalseClass], default: false
attribute :interactive_enabled, kind_of: [TrueClass, FalseClass], default: false
attribute :frequency_modifier, kind_of: Integer, default: 1
attribute :frequency, equal_to: [:minute,
:hourly,
:daily,
:weekly,
:monthly,
:once,
:on_logon,
:onstart,
:on_idle], default: :hourly
attribute :start_day, kind_of: String, default: nil
attribute :start_time, kind_of: String, default: nil
attribute :day, kind_of: [String, Integer], default: nil
attr_accessor :exists, :status, :enabled
def initialize(name, run_context = nil)
super
@action = :create
end

View File

@@ -1,33 +1,33 @@
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: zipfile
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :unzip, :zip
attribute :path, :kind_of => String, :name_attribute => true
attribute :source, :kind_of => String
attribute :overwrite, :kind_of => [ TrueClass, FalseClass ], :default => false
attribute :checksum, :kind_of => String
def initialize(name, run_context=nil)
super
@action = :unzip
end
#
# Author:: Doug MacEachern (<dougm@vmware.com>)
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Cookbook Name:: windows
# Resource:: zipfile
#
# Copyright:: 2010, VMware, Inc.
# Copyright:: 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
actions :unzip, :zip
attribute :path, kind_of: String, name_attribute: true
attribute :source, kind_of: String
attribute :overwrite, kind_of: [TrueClass, FalseClass], default: false
attribute :checksum, kind_of: String
def initialize(name, run_context = nil)
super
@action = :unzip
end