Fix host remote test InvokeOnRunspace to work with AppVeyor (#2362)

* Fix host remote test InvokeOnRunspace to work with AppVeyor

* Updated to use new local account for remoting tests.

* Set the LocalAccountTokenFilterPolicy as needed.

* Adding verbose messages for debugging.

* Storing creds using Export-CliXml

* Added CITravis skip for Windows only remoting test

* Moving tests back to 'Feature' scope

* Added AppVeyor environment variable check to prevent account creation on non-appveyor configurations

* Removed It block in BeforeAll block

* Moving tests back to 'Feature'
This commit is contained in:
Paul Higinbotham
2016-10-10 15:24:04 -07:00
committed by Travis Plunk
parent b211f5f59b
commit 3815482082
2 changed files with 147 additions and 7 deletions
+36 -7
View File
@@ -1,4 +1,29 @@
Describe "InvokeOnRunspace method argument error handling" -tags "Feature" {
function Get-RemoteRunspace {
$wc = [System.Management.Automation.Runspaces.WSManConnectionInfo]::new()
# Use AppVeyor credentials if running in AppVeyor, rather than implicit credentials.
try
{
$appveyorRemoteCredential = Import-Clixml -Path "$env:TEMP\AppVeyorRemoteCred.xml"
}
catch { }
if ($appveyorRemoteCredential)
{
Write-Verbose "Using global AppVeyor credential";
$wc.Credential = $appveyorRemoteCredential
}
else
{
Write-Verbose "Using implicit credentials"
}
$remoteRunspace = [runspacefactory]::CreateRunspace($host, $wc)
$remoteRunspace.Open()
return $remoteRunspace
}
Describe "InvokeOnRunspace method argument error handling" -tags "Feature" {
BeforeAll {
$command = [System.Management.Automation.PSCommand]::new()
@@ -49,21 +74,25 @@ Describe "InvokeOnRunspace method as nested command" -tags "Feature" {
Describe "InvokeOnRunspace method on remote runspace" -tags "Feature" {
BeforeAll {
$wc = [System.Management.Automation.Runspaces.WSManConnectionInfo]::new()
$remoteRunspace = [runspacefactory]::CreateRunspace($host, $wc)
$remoteRunspace.Open()
if ($IsWindows) {
$script:remoteRunspace = Get-RemoteRunspace
}
}
AfterAll {
$remoteRunspace.Dispose();
if ($script:remoteRunspace)
{
$script:remoteRunspace.Dispose();
}
}
It "Method should successfully invoke command on remote runspace" {
It "Method should successfully invoke command on remote runspace" -Skip:(!$IsWindows) {
$command = [System.Management.Automation.PSCommand]::new()
$command.AddScript('"Hello!"')
$results = [System.Management.Automation.HostUtilities]::InvokeOnRunspace($command, $remoteRunspace)
$results = [System.Management.Automation.HostUtilities]::InvokeOnRunspace($command, $script:remoteRunspace)
$results[0] | Should Be "Hello!"
}
+111
View File
@@ -1,8 +1,81 @@
$ErrorActionPreference = 'Stop'
$repoRoot = Join-Path $PSScriptRoot '..'
$script:administratorsGroupSID = "S-1-5-32-544"
$script:usersGroupSID = "S-1-5-32-545"
Import-Module (Join-Path $repoRoot 'build.psm1')
function New-LocalUser
{
<#
.SYNOPSIS
Creates a local user with the specified username and password
.DESCRIPTION
.EXAMPLE
.PARAMETER
username Username of the user which will be created
.PARAMETER
password Password of the user which will be created
.OUTPUTS
.NOTES
#>
param(
[Parameter(Mandatory=$true)]
[string] $username,
[Parameter(Mandatory=$true)]
[string] $password
)
$LocalComputer = [ADSI] "WinNT://$env:computername";
$user = $LocalComputer.Create('user', $username);
$user.SetPassword($password) | out-null;
$user.SetInfo() | out-null;
}
<#
Converts SID to NT Account Name
#>
function ConvertTo-NtAccount
{
param(
[Parameter(Mandatory=$true)]
[string] $sid
)
(new-object System.Security.Principal.SecurityIdentifier($sid)).translate([System.Security.Principal.NTAccount]).Value
}
<#
Add a user to a local security group
#>
function Add-UserToGroup
{
param(
[Parameter(Mandatory=$true)]
[string] $username,
[Parameter(Mandatory=$true, ParameterSetName = "SID")]
[string] $groupSid,
[Parameter(Mandatory=$true, ParameterSetName = "Name")]
[string] $group
)
$userAD = [ADSI] "WinNT://$env:computername/${username},user"
if($PsCmdlet.ParameterSetName -eq "SID")
{
$ntAccount=ConvertTo-NtAccount $groupSid
$group =$ntAccount.Split("\\")[1]
}
$groupAD = [ADSI] "WinNT://$env:computername/${group},group"
$groupAD.Add($userAD.AdsPath);
}
# tests if we should run a daily build
# returns true if the build is scheduled
# or is a pushed tag
@@ -105,6 +178,44 @@ function Invoke-AppVeyorInstall
Update-AppveyorBuild -message $buildName
}
if ($env:APPVEYOR)
{
#
# Generate new credential for appveyor (only) remoting tests.
#
Write-Verbose "Creating account for remoting tests in AppVeyor."
# Password
$randomObj = [System.Random]::new()
$password = ""
1..(Get-Random -Minimum 15 -Maximum 126) | ForEach { $password = $password + [char]$randomObj.next(45,126) }
# Account
$userName = 'appVeyorRemote'
New-LocalUser -username $userName -password $password
Add-UserToGroup -username $userName -groupSid $script:administratorsGroupSID
# Provide credentials globally for remote tests.
$ss = ConvertTo-SecureString -String $password -AsPlainText -Force
$appveyorRemoteCredential = [PSCredential]::new("$env:COMPUTERNAME\$userName", $ss)
$appveyorRemoteCredential | Export-Clixml -Path "$env:TEMP\AppVeyorRemoteCred.xml" -Force
# Check that LocalAccountTokenFilterPolicy policy is set, since it is needed for remoting
# using above local admin account.
Write-Verbose "Checking for LocalAccountTokenFilterPolicy in AppVeyor."
$haveLocalAccountTokenFilterPolicy = $false
try
{
$haveLocalAccountTokenFilterPolicy = ((Get-ItemPropertyValue -Path HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy) -eq 1)
}
catch { }
if (!$haveLocalAccountTokenFilterPolicy)
{
Write-Verbose "Setting the LocalAccountTokenFilterPolicy for remoting tests"
Set-ItemProperty -Path HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy -Value 1
}
}
Set-BuildVariable -Name TestPassed -Value False
Start-PSBootstrap -Force
}