diff options
author | Tim Smith <tsmith@chef.io> | 2018-01-19 21:41:25 -0800 |
---|---|---|
committer | Tim Smith <tsmith@chef.io> | 2018-02-23 21:11:01 -0800 |
commit | 00b9d510b68e87b77e8d3105280b4e8c8d6d1dbf (patch) | |
tree | 1dca0a1149940d64099ba59d0f85544b62652bd5 /lib/chef/resource | |
parent | e91fe995f8e93788f98ff32e1df4c0789b1a5a2a (diff) | |
download | chef-00b9d510b68e87b77e8d3105280b4e8c8d6d1dbf.tar.gz |
Add windows auto_run, font, pagefile, printer, printer_port, and shortcut resources
Ported from the Windows cookbook
Signed-off-by: Tim Smith <tsmith@chef.io>
Diffstat (limited to 'lib/chef/resource')
-rw-r--r-- | lib/chef/resource/windows_auto_run.rb | 87 | ||||
-rw-r--r-- | lib/chef/resource/windows_font.rb | 127 | ||||
-rw-r--r-- | lib/chef/resource/windows_pagefile.rb | 223 | ||||
-rw-r--r-- | lib/chef/resource/windows_printer.rb | 147 | ||||
-rw-r--r-- | lib/chef/resource/windows_printer_port.rb | 132 | ||||
-rw-r--r-- | lib/chef/resource/windows_shortcut.rb | 79 |
6 files changed, 795 insertions, 0 deletions
diff --git a/lib/chef/resource/windows_auto_run.rb b/lib/chef/resource/windows_auto_run.rb new file mode 100644 index 0000000000..9e5414f26e --- /dev/null +++ b/lib/chef/resource/windows_auto_run.rb @@ -0,0 +1,87 @@ +# +# Author:: Paul Morton (<pmorton@biaprotect.com>) +# Copyright:: 2011-2018, Business Intelligence Associates, Inc. +# Copyright:: 2017-2018, 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/resource" + +class Chef + class Resource + class WindowsAutorun < Chef::Resource + resource_name :windows_auto_run + provides :windows_auto_run + + description "Use the windows_auto_run resource to set applications to run at logon." + introduced "14.0" + + property :program_name, String, + description: "The name of the program to run at login if different from the resource name.", + name_property: true + + property :path, String, + coerce: proc { |x| x.tr("/", "\\") }, # make sure we have windows paths for the registry + description: "The path to the program to be run at login." + + property :args, String, + description: "Any arguments for the program." + + property :root, Symbol, + description: "The registry root key to put the entry under.", + equal_to: %i{machine user}, + default: :machine + + alias_method :program, :path + + action :create do + description "Create an item to be run at login." + + data = "\"#{new_resource.path}\"" + data << " #{new_resource.args}" if new_resource.args + + declare_resource(:registry_key, registry_path) do + values [{ + name: new_resource.program_name, + type: :string, + data: data, + }] + action :create + end + end + + action :remove do + description "Remove an item that was previously setup to run at login" + + declare_resource(:registry_key, registry_path) do + values [{ + name: new_resource.program_name, + type: :string, + data: "", + }] + action :delete + end + end + + action_class do + # determine the full registry path based on the root property + # @return [String] + def registry_path + { machine: "HKLM", user: "HKCU" }[new_resource.root] + \ + '\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run' + end + end + end + end +end diff --git a/lib/chef/resource/windows_font.rb b/lib/chef/resource/windows_font.rb new file mode 100644 index 0000000000..495abc787b --- /dev/null +++ b/lib/chef/resource/windows_font.rb @@ -0,0 +1,127 @@ +# +# Copyright:: 2014-2018, Schuberg Philis BV. +# Copyright:: 2017-2018, 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/resource" + +class Chef + class Resource + class WindowsFont < Chef::Resource + require "chef/util/path_helper" + + resource_name :windows_font + provides :windows_font + + description "Use the windows_font resource to install or remove font files on Windows."\ + " Sources the font by default from the cookbook using the resource, but a URI"\ + " source can be specified as well." + introduced "14.0" + + property :font_name, String, + description: "The file name of the font file name to install if different than the resource name.", + name_property: true + + property :source, String, + description: "A local filesystem path or URI to source the font file from.", + coerce: proc { |x| x =~ /^.:.*/ ? x.tr('\\', "/").gsub("//", "/") : x } + + action :install do + description "Install a font to the system fonts directory." + + if font_exists? + Chef::Log.debug("Not installing font: #{new_resource.font_name} as font already installed.") + else + retrieve_cookbook_font + install_font + del_cookbook_font + end + end + + action_class do + # if a source is specified fetch using remote_file. If not use cookbook_file + def retrieve_cookbook_font + font_file = new_resource.font_name + if new_resource.source + declare_resource(:remote_file, font_file) do + action :nothing + source source_uri + path Chef::Util::PathHelper.join(ENV["TEMP"], font_file) + end.run_action(:create) + else + declare_resource(:cookbook_file, font_file) do + action :nothing + cookbook cookbook_name.to_s unless cookbook_name.nil? + path Chef::Util::PathHelper.join(ENV["TEMP"], font_file) + end.run_action(:create) + end + end + + # delete the temp cookbook file + def del_cookbook_font + file Chef::Util::PathHelper.join(ENV["TEMP"], new_resource.font_name) do + action :delete + end + end + + # install the font into the appropriate fonts directory + def install_font + require "win32ole" if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + fonts_dir = WIN32OLE.new("WScript.Shell").SpecialFolders("Fonts") + folder = WIN32OLE.new("Shell.Application").Namespace(fonts_dir) + converge_by("install font #{new_resource.font_name} to #{fonts_dir}") do + folder.CopyHere(Chef::Util::PathHelper.join(ENV["TEMP"], new_resource.font_name)) + end + end + + # Check to see if the font is installed in the fonts dir + # + # @return [Boolean] Is the font is installed? + def font_exists? + require "win32ole" if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + fonts_dir = WIN32OLE.new("WScript.Shell").SpecialFolders("Fonts") + Chef::Log.debug("Seeing if the font at #{Chef::Util::PathHelper.join(fonts_dir, new_resource.font_name)} exists") + ::File.exist?(Chef::Util::PathHelper.join(fonts_dir, new_resource.font_name)) + end + + # Parse out the schema provided to us to see if it's one we support via remote_file. + # We do this because URI will parse C:/foo as schema 'c', which won't work with remote_file + # + # @return [Boolean] + def remote_file_schema?(schema) + return true if %w{http https ftp}.include?(schema) + end + + # return new_resource.source if we have a proper URI specified + # if it's a local file listed as a source return it in file:// format + # + # @return [String] path to the font + def source_uri + begin + require "uri" + if remote_file_schema?(URI.parse(new_resource.source).scheme) + Chef::Log.debug("source property starts with ftp/http. Using source property unmodified") + return new_resource.source + end + rescue URI::InvalidURIError + Chef::Log.warn("source property of #{new_resource.source} could not be processed as a URI. Check the format you provided.") + end + Chef::Log.debug("source property does not start with ftp/http. Prepending with file:// as it appears to be a local file.") + "file://#{new_resource.source}" + end + end + end + end +end diff --git a/lib/chef/resource/windows_pagefile.rb b/lib/chef/resource/windows_pagefile.rb new file mode 100644 index 0000000000..069e76107c --- /dev/null +++ b/lib/chef/resource/windows_pagefile.rb @@ -0,0 +1,223 @@ +# +# Copyright:: 2012-2018, Nordstrom, Inc. +# Copyright:: 2017-2018, 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. +# + +class Chef + class Resource + class WindowsPagefile < Chef::Resource + resource_name :windows_pagefile + provides :windows_pagefile + + description "Use the windows_pagefile resource to configure pagefile settings on Windows." + introduced "14.0" + + property :path, String, + coerce: proc { |x| x.tr('\\', "/") }, + description: "The path to the pagefile if different from the resource name.", + name_property: true + + property :system_managed, [true, false], + description: "Configures whether the system manages the pagefile size." + + property :automatic_managed, [true, false], + description: "Enable automatic management of pagefile initial and maximum size. Setting this to true ignores 'initial_size' and 'maximum_size' properties.", + default: false + + property :initial_size, Integer, + description: "Initial size of the pagefile in bytes." + + property :maximum_size, Integer, + description: "Maximum size of the pagefile in bytes." + + action :set do + description "Configures the default pagefile, creating if it doesn't exist." + + pagefile = new_resource.path + initial_size = new_resource.initial_size + maximum_size = new_resource.maximum_size + system_managed = new_resource.system_managed + automatic_managed = new_resource.automatic_managed + + if automatic_managed + set_automatic_managed unless automatic_managed? + else + unset_automatic_managed if automatic_managed? + + # 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 + validate_name + create(pagefile) unless exists?(pagefile) + + if system_managed + set_system_managed(pagefile) unless max_and_min_set?(pagefile, 0, 0) + else + unless max_and_min_set?(pagefile, initial_size, maximum_size) + set_custom_size(pagefile, initial_size, maximum_size) + end + end + end + end + end + + action :delete do + description "Deletes the specified pagefile." + + validate_name + delete(new_resource.path) if exists?(new_resource.path) + end + + action_class do + # 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 + + # make sure the provided name property matches the appropriate format + # we do this here and not in the property itself because if automatic_managed + # is set then this validation is not necessary / doesn't make sense at all + def validate_name + return if /^.:.*.sys/ =~ new_resource.path + raise "#{new_resource.path} does not match the format DRIVE:\\path\\file.sys for pagefiles. Example: C:\\pagefile.sys" + end + + # See if the pagefile exists + # + # @param [String] pagefile path to the pagefile + # @return [Boolean] + def exists?(pagefile) + @exists ||= begin + Chef::Log.debug("Checking if #{pagefile} exists by runing: #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" list /format:list") + 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 + + # is the max/min pagefile size set? + # + # @param [String] pagefile path to the pagefile + # @param [String] min the minimum size of the pagefile + # @param [String] max the minimum size of the pagefile + # @return [Boolean] + def max_and_min_set?(pagefile, min, max) + @max_and_min_set ||= begin + Chef::Log.debug("Checking if #{pagefile} min: #{min} and max #{max} are set") + 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 + + # create a pagefile + # + # @param [String] pagefile path to the pagefile + def create(pagefile) + converge_by("create pagefile #{pagefile}") do + Chef::Log.debug("Running #{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"") + cmd = shell_out("#{wmic} pagefileset create name=\"#{win_friendly_path(pagefile)}\"") + check_for_errors(cmd.stderr) + end + end + + # delete a pagefile + # + # @param [String] pagefile path to the pagefile + def delete(pagefile) + converge_by("remove pagefile #{pagefile}") do + Chef::Log.debug("Running #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete") + cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" delete") + check_for_errors(cmd.stderr) + end + end + + # see if the pagefile is automatically managed by Windows + # + # @return [Boolean] + def automatic_managed? + @automatic_managed ||= begin + Chef::Log.debug("Checking if pagefiles are automatically managed") + cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" get AutomaticManagedPagefile /format:list") + cmd.stderr.empty? && (cmd.stdout =~ /AutomaticManagedPagefile=TRUE/i) + end + end + + # turn on automatic management of all pagefiles by Windows + def set_automatic_managed + converge_by("set pagefile to Automatic Managed") do + Chef::Log.debug("Running #{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True") + cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=True") + check_for_errors(cmd.stderr) + end + end + + # turn off automatic management of all pagefiles by Windows + def unset_automatic_managed + converge_by("set pagefile to User Managed") do + Chef::Log.debug("Running #{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False") + cmd = shell_out("#{wmic} computersystem where name=\"%computername%\" set AutomaticManagedPagefile=False") + check_for_errors(cmd.stderr) + end + end + + # set a custom size for the pagefile (vs the defaults) + # + # @param [String] pagefile path to the pagefile + # @param [String] min the minimum size of the pagefile + # @param [String] max the minimum size of the pagefile + def set_custom_size(pagefile, min, max) + converge_by("set #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}") do + Chef::Log.debug("Running #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set 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 + end + + # set a pagefile size to be system managed + # + # @param [String] pagefile path to the pagefile + def set_system_managed(pagefile) + converge_by("set #{pagefile} to System Managed") do + Chef::Log.debug("Running #{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0") + cmd = shell_out("#{wmic} pagefileset where SettingID=\"#{get_setting_id(pagefile)}\" set InitialSize=0,MaximumSize=0", returns: [0]) + check_for_errors(cmd.stderr) + end + end + + def get_setting_id(pagefile) + pagefile = win_friendly_path(pagefile) + pagefile = pagefile.split('\\') + "#{pagefile[1]} @ #{pagefile[0]}" + end + + # raise if there's an error on stderr on a shellout + def check_for_errors(stderr) + raise stderr.chomp unless stderr.empty? + end + + def wmic + @wmic ||= locate_sysnative_cmd("wmic.exe") + end + end + end + end +end diff --git a/lib/chef/resource/windows_printer.rb b/lib/chef/resource/windows_printer.rb new file mode 100644 index 0000000000..c134e27bf7 --- /dev/null +++ b/lib/chef/resource/windows_printer.rb @@ -0,0 +1,147 @@ +# +# Author:: Doug Ireton (<doug@1strategy.com>) +# Copyright:: 2012-2018, 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 "chef/resource" + +class Chef + class Resource + class WindowsPrinter < Chef::Resource + require "resolv" + + resource_name :windows_printer + provides :windows_printer + + description "Use the windows_printer resource to setup Windows printers. Note"\ + " that this doesn't currently install a printer driver. You must"\ + " already have the driver installed on the system." + introduced "14.0" + + property :device_id, String, + description: "Printer queue name, e.g. 'HP LJ 5200 in fifth floor copy room'.", + name_property: true + + property :comment, String, + description: "Optional descriptor for the printer queue." + + property :default, [true, false], + description: "Should this be the system's default printer.", + default: false + + property :driver_name, String, + description: "Exact name of printer driver. Note that the printer driver must already be installed on the node.", + required: true + + property :location, String, + description: "Printer location, e.g. 'Fifth floor copy room'." + + property :shared, [true, false], + description: "Should the printer be shared.", + default: false + + property :share_name, String, + description: "The name to share the printer as." + + property :ipv4_address, String, + description: "Printer IPv4 address, e.g. '10.4.64.23'.", + validation_message: "The ipv4_address property must be in the IPv4 format of WWW.XXX.YYY.ZZZ", + regex: Resolv::IPv4::Regex + + property :exists, [true, false], desired_state: true + + PRINTERS_REG_KEY = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\\'.freeze unless defined?(PRINTERS_REG_KEY) + + # does the printer exist + # + # @param [String] name the name of the printer + # @return [Boolean] + 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 + + # @todo Set @current_resource printer properties from registry + load_current_value do |desired| + name desired.name + exists printer_exists?(desired.name) + end + + action :create do + description "Create a new printer and a printer port if one doesn't already exist." + + 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 + description "Delete an existing printer. Note this does not delete the associated printer port." + + 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 + + action_class do + # creates the printer port and then the printer + def create_printer + # Create the printer port first + windows_printer_port new_resource.ipv4_address do + end + + port_name = "IP_#{new_resource.ipv4_address}" + + declare_resource(: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 + declare_resource(: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 + end + end + end +end diff --git a/lib/chef/resource/windows_printer_port.rb b/lib/chef/resource/windows_printer_port.rb new file mode 100644 index 0000000000..9da43948f6 --- /dev/null +++ b/lib/chef/resource/windows_printer_port.rb @@ -0,0 +1,132 @@ +# +# Author:: Doug Ireton <doug@1strategy.com> +# Copyright:: 2012-2018, 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 "chef/resource" + +class Chef + class Resource + class WindowsPrinterPort < Chef::Resource + require "resolv" + + resource_name :windows_printer_port + provides :windows_printer_port + + description "Use the windows_printer_port resoruce to create and delete TCP/IPv4 printer ports on Windows" + introduced "14.0" + + property :ipv4_address, String, + name_property: true, + regex: Resolv::IPv4::Regex, + validation_message: "The ipv4_address property must be in the format of WWW.XXX.YYY.ZZZ!", + description: "The IPv4 address of the printer port." + + property :port_name, String, + description: "The port name." + + property :port_number, Integer, + description: "The port number.", + default: 9100 + + property :port_description, String, + description: "The description of the port." + + property :snmp_enabled, [true, false], + description: "Should SNMP be enabled on the port.", + default: false + + property :port_protocol, Integer, + description: "The printer port protocol, 1 (RAW), or 2 (LPR).", + validation_message: "port_protocol must be either 1 for RAW or 2 for LPR!", + default: 1, equal_to: [1, 2] + + property :exists, [true, false], + desired_state: true + + 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 + + # @todo Set @current_resource port properties from registry + load_current_value do |desired| + name desired.name + ipv4_address desired.ipv4_address + port_name desired.port_name || "IP_#{desired.ipv4_address}" + exists port_exists?(desired.port_name || "IP_#{desired.ipv4_address}") + 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 + + action_class do + def create_printer_port + port_name = new_resource.port_name || "IP_#{new_resource.ipv4_address}" + + # create the printer port using PowerShell + declare_resource(: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}" + + declare_resource(: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 + end + end + end +end diff --git a/lib/chef/resource/windows_shortcut.rb b/lib/chef/resource/windows_shortcut.rb new file mode 100644 index 0000000000..7e88a8c460 --- /dev/null +++ b/lib/chef/resource/windows_shortcut.rb @@ -0,0 +1,79 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: 2010-2018, VMware, Inc. +# Copyright:: 2017-2018, 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/resource" + +class Chef + class Resource + class WindowsShortcut < Chef::Resource + resource_name :windows_shortcut + provides :windows_shortcut + + description "Use the windows_shortcut resource to create shortcut files on Windows" + introduced "14.0" + + property :shortcut_name, String, + description: "The name for the shortcut if it differs from the resource name.", + name_property: true + + property :target, String, + description: "Where the shortcut links to." + + property :arguments, String, + description: "Arguments to pass to the target when the shortcut is executed." + + property :description, String, + description: "The description of the shortcut" + + property :cwd, String, + description: "Working directory to use when the target is executed." + + property :iconlocation, String, + description: "Icon to use for the shortcut, in the format of 'path, index'. Index is the icon file to use. See https://msdn.microsoft.com/en-us/library/3s9bx7at.aspx for details" + + load_current_value do |desired| + require "win32ole" if RUBY_PLATFORM =~ /mswin|mingw32|windows/ + + link = WIN32OLE.new("WScript.Shell").CreateShortcut(desired.shortcut_name) + name desired.shortcut_name + target(link.TargetPath) + arguments(link.Arguments) + description(link.Description) + cwd(link.WorkingDirectory) + iconlocation(link.IconLocation) + end + + action :create do + description "Create or modify a Windows shortcut." + + converge_if_changed do + converge_by "creating shortcut #{new_resource.shortcut_name}" do + link = WIN32OLE.new("WScript.Shell").CreateShortcut(new_resource.shortcut_name) + 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 + end + end + end + end + end +end |