Cant read powershell output to variable


#1

Hi,

Problem statement : I want to store powershell cmd output to variable and use the variable in the whole recipe wherever it is required.

i tried but not able to do it. kindly help me.

powershell_script 'get-python-version' do
    code 'version = (Get-WmiObject -Class Win32_Product | Select-Object -Property Name | Select-String -Pattern "Python") -replace "@{Name=", "" -replace "}", ""'
     guard_interpreter :powershell_script
end

windows_package "#{version}" do
  action :remove
end

Regards,
vagga06


#2

HI @vagga06,

The version variable only lives within the code block of your powershell_script resource. It will not be a global variable and you will not be able to reference it by other resources.
What you are looking for is the powershell_out mixin

require "chef/mixin/powershell_out"
include Chef::Mixin::PowershellOut

script = <<-EOH
 # your_awsome_ps_script
EOH

result = powershell_out(script)

The source code:


#3

Thank you @simark.

after adding above code , i am getting below error.

NoMethodError

undefined method `include’ for cookbook: python2.7.12, recipe: install :Chef::Recipe

Modified code :

require "chef/mixin/powershell_out"
include Chef::Mixin::PowershellOut

script = <<-EOH
     	(Get-WmiObject -Class Win32_Product | Select-Object -Property Name | Select-String -Pattern "Python") -replace "@{Name=", "" -replace "}", ""
    EOH

result = powershell_out(script)

windows_package "#{result}" do
  action :remove
end 

is there anything i need to add, kindly suggest

Regards,
Vagga06


#4

Since you are in instance of a Chef::Recipe and the include is not part of the DSL you have to use

::Chef::Recipe.send(:include, Chef::Mixin::PowershellOut)

instead of

include Chef::Mixin::PowershellOut

further information:
https://github.com/chef/chef/issues/2234


#5

Depending on how python was installed, ohai may already know the package version.

ohai packages
{
  "7-Zip 16.04 (x64)": {
    "version": "16.04",
    "publisher": "Igor Pavlov"
  },
  "Git version 2.15.0": {
    "version": "2.15.0",
    "publisher": "The Git Development Community",
    "installdate": "20171109"
  },
  "ConEmu 171025.x64": {
    "version": "11.171.0250",
    "publisher": "ConEmu-Maximus5",
    "installdate": "20171110"
  },
  "Chef Client v12.21.20": {
    "version": "12.21.20.1",
    "publisher": "Chef Software, Inc.",
    "installdate": "20171025"
  }
}

You can access the packages attributes like this

node['packages']['Git version 2.15.0']['version']

#6

I believe using Ohai is the best way to do this however using PowerShell in this way like the OP wants to is not a bad idea for edge cases and something that I’ve done. In addition if you’re not great with Ruby this might be useful.


#7

Hi,

Thank you for your reply :smile:

I am trying to find the version of python installed (manual) in windows server and compare with the one which i am going to install through chef. if versions are different then chef will uninstall old python and install specified version in cookbook.

I need to find out the old version of python and remove it from windows machine, as i mentioned in the above thread , i am not able to read the output (old python version) into variable from powershell and use that variable to remove package.

Below is my installation script , if possible please modify it and help.

powershell_script 'check-python-status' do
    code "$true"
    flags '-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass'
    guard_interpreter :powershell_script
    only_if 'If ((Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -eq "Python 2.7.12 (64-bit)"}) -eq $null) { Return $True } Return $False'
    notifies :install, 'windows_package node['python2.7.12']['package_name']', :immediate
end


windows_package node['python2.7.12']['package_name'] do
  source node['python2.7.12']['url']
  checksum "#{node['python2.7.12']['checksum']}"
end

#Add python installation path to environment variable 'path'
env 'Path' do
   delim ";"
   value "#{node['python2.7.12']['path']}"
   :modify
end

#add python scirpts path to environment variable 'path'  
env 'Path' do
   delim ";"
   value "#{node['python2.7.12']['path']}\\Scripts"
   :modify
end