added code for puppet provisioning.
This commit is contained in:
DeeJay 2014-03-28 19:55:19 +05:30
Родитель b4ee15e5d0
Коммит 0baec895d7
17 изменённых файлов: 741 добавлений и 16 удалений

Просмотреть файл

@ -12,6 +12,9 @@ module VagrantPlugins
autoload :Action, lib_path.join('action')
autoload :Error, lib_path.join('errors')
monkey_patch = Pathname.new(File.expand_path("../vagrant-azure/monkey_patch", __FILE__))
require monkey_patch.join("util/powershell")
# This returns the path to the source of this plugin.
#
# @return [Pathname]
@ -20,4 +23,3 @@ module VagrantPlugins
end
end
end

Просмотреть файл

@ -1,12 +1,7 @@
#---------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
# Overriding the core vagrant class because of the lack of non-ssh based
# communication infrastructure.
# This will be moved to an 'rdp' communicator when the core supports it.
#---------------------------------------------------------------------------
module VagrantPlugins
module WinAzure
module Action
@ -17,14 +12,23 @@ module VagrantPlugins
env[:machine].id =~ /@/
vm = env[:azure_vm_service].get_virtual_machine($`, $')
env[:ui].info "VM OS: #{vm.os_type.to_s}"
env[:ui].info "VM OS: #{vm.os_type.to_sym}"
if vm.os_type.to_s == :Windows
if vm.os_type.to_sym == :Windows
# Raise an error if we're not on a Windows Host.
# Non-Windows OS will be supported once we move to WinRb/WinRm
env[:ui].info "Is Host OS Windows?: #{Vagrant::Util::Platform.windows?}"
raise 'Unsupported OS for Windows Provisioning' unless \
Vagrant::Util::Platform.windows?
env[:ui].info "Provisioning for Windows"
# TODO: Add Shell, Chef-solo and other provisioners
case env[:provisioner].class.to_s
when "VagrantPlugins::Puppet::Provisioner::Puppet"
VagrantPlugins::WinAzure::Provisioner::Puppet.new(
env
).provision_for_windows
end
else
env[:ui].info "Provisioning using SSH"
env[:provisioner].provision

Просмотреть файл

@ -59,10 +59,31 @@ module VagrantPlugins
options[:availability_set_name] = config.availability_set_name unless \
config.availability_set_name.nil?
add_role = config.add_role
add_role = false
env[:ui].info(params.inspect)
env[:ui].info(options.inspect)
# Check if the cloud service exists and if yes, does it contain
# a deployment.
if config.cloud_service_name && !config.cloud_service_name.empty?
begin
cloud_service = ManagementHttpRequest.new(
:get,
"/services/hostedservices/#{config.cloud_service_name}?embed-detail=true"
).call
deployments = cloud_service.css 'HostedService Deployments Deployment'
# Lets see if any deployments exist. Set add_role = true if yes.
# We're not worried about deployment slots, because the SDK has
# hard coded 'Production' as deployment slot and you can have only
# one deployment per deployment slot.
add_role = deployments.length == 1
rescue Exception => e
add_role = false
end
end
env[:ui].info("Add Role? - #{add_role}")
server = env[:azure_vm_service].create_virtual_machine(

Просмотреть файл

@ -3,6 +3,7 @@
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
require 'vagrant'
require 'azure'
module VagrantPlugins
module WinAzure
@ -29,7 +30,6 @@ module VagrantPlugins
attr_accessor :vm_size
attr_accessor :winrm_transport
attr_accessor :availability_set_name
attr_accessor :add_role
attr_accessor :state_read_timeout
@ -56,7 +56,6 @@ module VagrantPlugins
@vm_size = UNSET_VALUE
@winrm_transport = UNSET_VALUE
@availability_set_name = UNSET_VALUE
@add_role = UNSET_VALUE
@state_read_timeout = UNSET_VALUE
end
@ -89,9 +88,21 @@ module VagrantPlugins
@winrm_transport = nil if @winrm_transport == UNSET_VALUE
@availability_set_name = nil if @availability_set_name == UNSET_VALUE
@add_role = false if @add_role == UNSET_VALUE
@state_read_timeout = 360 if @state_read_timeout == UNSET_VALUE
# This done due to a bug in Ruby SDK - it doesn't generate a storage
# account name if add_role = true
if @storage_acct_name.nil? || @storage_acct_name.empty?
@storage_acct_name = Azure::Core::Utility.random_string(
"#{@vm_name}storage"
).gsub(/[^0-9a-z ]/i, '').downcase[0..23]
end
if @cloud_service_name.nil? || @cloud_service_name.empty?
@cloud_service_name = Azure::Core::Utility.random_string(
"#{@vm_name}-service-"
)
end
end
def merge(other)
@ -122,8 +133,6 @@ module VagrantPlugins
# Azure Virtual Machine related validation
errors << "vagrant_azure.vm_name.required" if @vm_name.nil?
errors << "vagrant_azure.cloud_serivce_name.required" if \
@cloud_service_name.nil?
{ "Windows Azure Provider" => errors }
end

Просмотреть файл

@ -0,0 +1,77 @@
#---------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
require 'json'
require "#{Vagrant::source_root}/plugins/providers/hyperv/driver"
require 'vagrant/util/powershell'
module VagrantPlugins
module WinAzure
class Driver < VagrantPlugins::HyperV::Driver
def initialize(machine)
@id = machine.id
@machine = machine
end
def ssh_info
@ssh_info ||= machine.ssh_info
end
def remote_credentials
@remote_credentials ||= {
guest_ip: ssh_info[:host],
username: ssh_info[:username],
password: ssh_info[:password]
}
end
def run_remote_ps(command, &block)
options = remote_credentials.merge(command: command)
script_path = local_script_path('run_in_remote.ps1')
ps_options = []
options.each do |key, value|
ps_options << "-#{key}"
ps_options << "'#{value}'"
end
ps_options << '-ErrorAction' << 'Stop'
opts = { notify: [:stdout, :stderr, :stdin] }
Vagrant::Util::PowerShell.execute(
script_path,
*ps_options,
**opts,
&block
)
end
def upload(from, to)
options = {
vm_id: vm_id,
host_path: windows_path(from),
guest_path: windows_path(to)
}.merge(remote_credentials)
script_path = local_script_path('upload_file.ps1')
execute(script_path, remote_credentials)
end
protected
def local_script_path(path)
lib_path = Pathname.new(File.expand_path('../scripts', __FILE__))
lib_path.join(path).to_s
end
def windows_path(path)
if path
path = path.gsub('/', '\\')
path = "c:#{path}" if path =~ /^\\/
end
path
end
end
end
end

Просмотреть файл

@ -0,0 +1,37 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
require "#{Vagrant::source_root}/lib/vagrant/util/which"
require "#{Vagrant::source_root}/lib/vagrant/util/subprocess"
module Vagrant
module Util
# Executes PowerShell scripts.
#
# This is primarily a convenience wrapper around Subprocess that
# properly sets powershell flags for you.
class PowerShell
# Monkey patch to fix a bug with Vagrant 1.5.1.
# https://github.com/mitchellh/vagrant/issues/3192.
# This has been fixed in 1.5.2. by
# https://github.com/jyggen/vagrant/commit/d7320399e2497aae9b9c3fa83d94b7210d21bfb5
def self.execute(path, *args, **opts, &block)
command = [
"powershell",
"-NoProfile",
"-ExecutionPolicy", "Bypass",
"&('#{path}')",
args
].flatten
# Append on the options hash since Subprocess doesn't use
# Ruby 2.0 style options yet.
command << opts
Subprocess.execute(*command, &block)
end
end
end
end

Просмотреть файл

@ -4,12 +4,18 @@
#--------------------------------------------------------------------------
require 'log4r'
require 'vagrant'
require_relative 'driver'
module VagrantPlugins
module WinAzure
class Provider < Vagrant.plugin('2', :provider)
attr_reader :driver
def initialize(machine)
@machine = machine
# Load the driver
machine_id_changed
end
def action(name)
@ -21,6 +27,10 @@ module VagrantPlugins
nil
end
def machine_id_changed
@driver = Driver.new(@machine)
end
def ssh_info
# Run a custom action called "read_ssh_info" which does what it
# says and puts the resulting SSH info into the `:machine_ssh_info`

Просмотреть файл

@ -0,0 +1,109 @@
#---------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#---------------------------------------------------------------------------
require 'fileutils'
require 'tempfile'
module VagrantPlugins
module WinAzure
module Provisioner
class Puppet
attr_reader :provisioner
def initialize(env)
@env = env
@provisioner = env[:provisioner]
end
def provision_for_windows
options = [config.options].flatten
@module_paths = provisioner.instance_variable_get('@module_paths')
@hiera_config_path = provisioner.instance_variable_get(
'@hiera_config_path'
)
@manifest_file = provisioner.instance_variable_get('@manifest_file')
# Copy the manifests directory to the guest
if config.manifests_path[0].to_sym == :host
@env[:machine].provider.driver.upload(
File.expand_path(
config.manifests_path[1], @env[:machine].env.root_path
),
provisioner.manifests_guest_path
)
end
# Copy the module paths to the guest
@module_paths.each do |from, to|
@env[:machine].provider.driver.upload(from, to)
end
module_paths = @module_paths.map { |_, to| to }
unless module_paths.empty?
# Prepend the default module path
module_paths.unshift('/ProgramData/PuppetLabs/puppet/etc/modules')
# Add the command line switch to add the module path
options << "--modulepath '#{module_paths.join(':')}'"
end
if @hiera_config_path
options << "--hiera_config=#{@hiera_config_path}"
# Upload Hiera configuration if we have it
local_hiera_path = File.expand_path(
config.hiera_config_path,
@env[:machine].env.root_path
)
@env[:machine].provider.driver.upload(
local_hiera_path,
@hiera_config_path
)
end
options << "--manifestdir #{provisioner.manifests_guest_path}"
options << "--detailed-exitcodes"
options << @manifest_file
options = options.join(' ')
# Build up the custome facts if we have any
facter = ''
unless config.facter.empty?
facts = []
config.facter.each do |key, value|
facts << "FACTER_#{key}='#{value}'"
end
facter = "#{facts.join(' ')}"
end
command = "#{facter}puppet apply #{options}"
if config.working_directory
command = "cd #{config.working_directory} && #{command}"
end
@env[:ui].info I18n.t(
'vagrant_azure.provisioners.puppet.running_puppet',
manifest: config.manifest_file
)
@env[:ui].info 'Executing puppet script in Windows Azure VM'
@env[:machine].provdier.driver.run_remote_ps(command) do |type, data|
# Output the data with the proper color based on the stream.
if (type == :stdout || type == :stderr)
@env[:ui].detail data
end
end
end
protected
def config
provisioner.config
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,41 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
param (
[string]$guest_ip = $(throw "-guest_ip is required."),
[string]$username = $(throw "-guest_username is required."),
[string]$password = $(throw "-guest_password is required.")
)
# Include the following modules
$presentDir = Split-Path -parent $PSCommandPath
. ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
. ([System.IO.Path]::Combine($presentDir, "utils\create_session.ps1"))
try {
$response = Create-Remote-Session $guest_ip $username $password
if (!$response["session"] -and $response["error"]) {
Write-Host $response["error"]
return
}
function Remote-Execute() {
$winrm_state = ""
get-service winrm | ForEach-Object {
$winrm_state = $_.status
}
return "$winrm_state"
}
$result = Invoke-Command -Session $response["session"] -ScriptBlock ${function:Remote-Execute} -ErrorAction "stop"
$resultHash = @{
message = "$result"
}
Write-Output-Message $resultHash
} catch {
$errortHash = @{
type = "PowerShellError"
error ="Failed to copy file $_"
}
Write-Error-Message $errortHash
return
}

Просмотреть файл

@ -0,0 +1,31 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
param (
[string]$vm_id = $(throw "-vm_id is required."),
[string]$path = $(throw "-path is required.")
)
# Include the following modules
$presentDir = Split-Path -parent $PSCommandPath
. ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
# Export the Virtual Machine
try {
$vm = Get-Vm -Id $vm_id
$vm | Export-VM -Path $path -ErrorAction "stop"
$name = $vm.name
$resultHash = @{
name = "$name"
}
Write-Output-Message $resultHash
} catch {
$errortHash = @{
type = "PowerShellError"
error = "Failed to export a VM $_"
}
Write-Error-Message $errortHash
}

Просмотреть файл

@ -0,0 +1,145 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
param (
[string]$vm_id = $(throw "-vm_id is required."),
[string]$guest_ip = $(throw "-guest_ip is required."),
[string]$username = $(throw "-guest_username is required."),
[string]$password = $(throw "-guest_password is required."),
[string]$host_path = $(throw "-host_path is required."),
[string]$guest_path = $(throw "-guest_path is required.")
)
# Include the following modules
$presentDir = Split-Path -parent $PSCommandPath
$modules = @()
$modules += $presentDir + "\utils\write_messages.ps1"
$modules += $presentDir + "\utils\create_session.ps1"
forEach ($module in $modules) { . $module }
function Get-file-hash($source_path, $delimiter) {
$source_files = @()
(Get-ChildItem $source_path -rec -force | ForEach-Object -Process {
Get-FileHash -Path $_.FullName -Algorithm MD5 } ) |
ForEach-Object -Process {
$source_files += $_.Path.Replace($source_path, "") + $delimiter + $_.Hash
}
$source_files
}
function Get-remote-file-hash($source_path, $delimiter, $session) {
Invoke-Command -Session $session -ScriptBlock ${function:Get-file-hash} -ArgumentList $source_path, $delimiter
# TODO:
# Check if remote PS Scripting errors
}
function Sync-Remote-Machine($machine, $remove_files, $copy_files, $host_path, $guest_path) {
ForEach ($item in $copy_files) {
$from = $host_path + $item
$to = $guest_path + $item
# Copy VM can also take a VM object
Copy-VMFile -VM $machine -SourcePath $from -DestinationPath $to -CreateFullPath -FileSource Host -Force
}
}
function Create-Remote-Folders($empty_source_folders, $guest_path) {
ForEach ($item in $empty_source_folders) {
$new_name = $guest_path + $item
New-Item "$new_name" -type directory -Force
}
}
function Create-Guest-Folder($guest_path) {
try {
if (Test-Path $guest_path) {
$junction = Get-Item $guest_path
$junction.Delete()
}
}
# Catch any [IOException]
catch {
Remove-Item "$guest_path" -Force -Recurse
}
New-Item "$guest_path" -type directory -Force
}
function Get-Empty-folders-From-Source($host_path) {
Get-ChildItem $host_path -recurse |
Where-Object {$_.PSIsContainer -eq $True} |
Where-Object {$_.GetFiles().Count -eq 0} |
Select-Object FullName | ForEach-Object -Process {
$empty_source_folders += ($_.FullName.Replace($host_path, ""))
}
}
$delimiter = " || "
$machine = Get-VM -Id $vm_id
# FIXME: PowerShell guys please fix this.
# The below script checks for all VMIntegrationService which are not enabled
# and will enable this.
# When when all the services are enabled this throws an error.
# Enable VMIntegrationService to true
try {
Get-VM -Id $vm_id | Get-VMIntegrationService -Name "Guest Service Interface" | Enable-VMIntegrationService -Passthru
}
catch { }
$response = Create-Remote-Session $guest_ip $username $password
if (!$response["session"] -and $response["error"]) {
$errortHash = @{
type = "PowerShellError"
error = $response["error"]
}
Write-Error-Message $errortHash
return
}
$session = $response["session"]
# Create the guest folder if not exist
$result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Guest-Folder} -ArgumentList $guest_path
$source_files = Get-file-hash $host_path $delimiter
$destination_files = Get-remote-file-hash $guest_path $delimiter $session
if (!$destination_files) {
$destination_files = @()
}
if (!$source_files) {
$source_files = @()
}
# Compare source and destination files
$remove_files = @()
$copy_files = @()
Compare-Object -ReferenceObject $source_files -DifferenceObject $destination_files | ForEach-Object {
if ($_.SideIndicator -eq '=>') {
$remove_files += $_.InputObject.Split($delimiter)[0]
} else {
$copy_files += $_.InputObject.Split($delimiter)[0]
}
}
# Update the files to remote machine
Sync-Remote-Machine $machine $remove_files $copy_files $host_path $guest_path
# Create any empty folders which missed to sync to remote machine
$empty_source_folders = @()
$directories = Get-Empty-folders-From-Source $host_path
$result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Remote-Folders} -ArgumentList $empty_source_folders, $guest_path
# Always remove the connection after Use
Remove-PSSession -Id $session.Id
$resultHash = @{
message = "OK"
}
Write-Output-Message $resultHash

Просмотреть файл

@ -0,0 +1,25 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
# Include the following modules
$presentDir = Split-Path -parent $PSCommandPath
. ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
try {
$hostname = $(whoami)
$ip = (Get-WmiObject -class win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"').ipaddress[0]
$resultHash = @{
host_name = "$username"
host_ip = "$ip"
}
Write-Output-Message $resultHash
}
catch {
$errortHash = @{
type = "PowerShellError"
error = "$_"
}
Write-Error-Message $errortHash
}

Просмотреть файл

@ -0,0 +1,36 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
param (
[string]$vm_id = $(throw "-vm_id is required."),
[string]$command = ""
)
# Include the following modules
$presentDir = Split-Path -parent $PSCommandPath
. ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
try {
$vm = Get-VM -Id $vm_id -ErrorAction "stop"
switch ($command) {
"start" { Start-VM $vm }
"stop" { Stop-VM $vm }
"suspend" { Suspend-VM $vm }
"resume" { Resume-VM $vm }
}
$state = $vm.state
$status = $vm.status
$name = $vm.name
} catch [Microsoft.HyperV.PowerShell.VirtualizationOperationFailedException] {
$state = "not_created"
$status = "Not Created"
}
$resultHash = @{
state = "$state"
status = "$status"
name = "$name"
}
Write-Output-Message $resultHash

Просмотреть файл

@ -0,0 +1,31 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
param (
[string]$guest_ip = $(throw "-guest_ip is required."),
[string]$username = $(throw "-guest_username is required."),
[string]$password = $(throw "-guest_password is required."),
[string]$command = ""
)
# Include the following modules
$presentDir = Split-Path -parent $PSCommandPath
. ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
. ([System.IO.Path]::Combine($presentDir, "utils\create_session.ps1"))
try {
$response = Create-Remote-Session $guest_ip $username $password
if (!$response["session"] -and $response["error"]) {
Write-Host $response["error"]
return
}
function Remote-Execute($command) {
cmd /c $command
}
Invoke-Command -Session $response["session"] -ScriptBlock ${function:Remote-Execute} -ArgumentList $command -ErrorAction "stop"
} catch {
Write-Host $_
return
}

Просмотреть файл

@ -0,0 +1,95 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
param (
[string]$vm_id = $(throw "-vm_id is required."),
[string]$host_path = $(throw "-host_path is required."),
[string]$guest_path = $(throw "-guest_path is required."),
[string]$guest_ip = $(throw "-guest_ip is required."),
[string]$username = $(throw "-guest_username is required."),
[string]$password = $(throw "-guest_password is required.")
)
# Include the following modules
$presentDir = Split-Path -parent $PSCommandPath
. ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
. ([System.IO.Path]::Combine($presentDir, "utils\create_session.ps1"))
try {
# Enable Guest Service Interface if they are disabled
try {
Get-VM -Id $vm_id | Get-VMIntegrationService -Name "Guest Service Interface" | Enable-VMIntegrationService -Passthru
}
catch { }
function Upload-FIle-To-VM($host_path, $guest_path, $machine) {
Write-Host $host_path
Write-Host $guest_path
Copy-VMFile -VM $machine -SourcePath $host_path -DestinationPath $guest_path -CreateFullPath -FileSource Host -Force -ErrorAction stop
}
function Prepare-Guest-Folder($guest_ip, $username, $password) {
$response = Create-Remote-Session $guest_ip $username $password
if (!$response["session"] -and $response["error"]) {
$errortHash = @{
type = "PowerShellError"
message = $response["error"]
}
Write-Error-Message $errorResult
return
}
$session = $response["session"]
# Create the guest folder if not exist
$result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Guest-Folder} -ArgumentList $guest_path
}
function Create-Guest-Folder($guest_path) {
try {
if (Test-Path $guest_path) {
# First attempt to remove a Junction drive. The fall back to removing a
# folder
$junction = Get-Item $guest_path
$junction.Delete()
}
}
# Catch any [IOException]
catch {
Remove-Item "$guest_path" -Force -Recurse
}
New-Item "$guest_path" -type directory -Force
}
$machine = Get-VM -Id $vm_id
# When Host path is a folder.
# Find all files within it and copy to the Guest
if (Test-Path $host_path -pathtype container) {
# Open a remote PS Session with the guest
Prepare-Guest-Folder $guest_ip $username $password
# Copy all files from Host path to Guest Path
Get-ChildItem $host_path -rec |
Where-Object {$_.PSIsContainer -eq $false} |
ForEach-Object -Process {
$file_name = $_.Fullname.Replace($host_path, "")
$from = $host_path + $file_name
$to = $guest_path + $file_name
# Write-Host $from
# Write-Host $to
Upload-FIle-To-VM $from $to $machine
}
} elseif (Test-Path $host_path) {
Upload-FIle-To-VM $host_path $guest_path $machine
}
$resultHash = @{
message = "OK"
}
Write-Output-Message $resultHash
} catch {
$errortHash = @{
type = "PowerShellError"
error ="Failed to copy file $_"
}
Write-Error-Message $errortHash
return
}

Просмотреть файл

@ -0,0 +1,34 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
function Get-Remote-Session($guest_ip, $username, $password) {
$secstr = convertto-securestring -AsPlainText -Force -String $password
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
New-PSSession -ComputerName $guest_ip -Credential $cred -ErrorAction "stop"
}
function Create-Remote-Session($guest_ip, $username, $password) {
$count = 0
$session_error = ""
$session = ""
do {
$count++
try {
$session = Get-Remote-Session $guest_ip $username $password
$session_error = ""
}
catch {
Start-Sleep -s 1
$session_error = $_
$session = ""
}
}
while (!$session -and $count -lt 20)
return @{
session = $session
error = $session_error
}
}

Просмотреть файл

@ -0,0 +1,18 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
function Write-Error-Message($message) {
$result = ConvertTo-Json $message
Write-Host "===Begin-Error==="
Write-Host $result
Write-Host "===End-Error==="
}
function Write-Output-Message($message) {
$result = ConvertTo-Json $message
Write-Host "===Begin-Output==="
Write-Host $result
Write-Host "===End-Output==="
}