Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Powershell on target machine version V1 and window machine file copy … #7500

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions Tasks/PowerShellOnTargetMachinesV1/ConfigureWinRM.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#################################################################################################################################
# Name : Configure-WinRM.ps1 #
# #
# Description : Configures the WinRM on a local machine #
# #
# Arguments : HostName, specifies the ipaddress or FQDN of machine #
#################################################################################################################################

param
(
[string] $hostname,
[string] $protocol
)

#################################################################################################################################
# Helper Functions #
#################################################################################################################################

$ErrorActionPreference="Stop"
$winrmHttpPort=5985
$winrmHttpsPort=5986

$helpMsg = "Usage:
To configure WinRM over Https:
./ConfigureWinRM.ps1 <fqdn\ipaddress>

To configure WinRM over Http:
./ConfigureWinRM.ps1 <fqdn\ipaddress> http"


function Is-InputValid
{
param([string] $hostname)

$isInputValid = $true

if(-not $hostname -or ($protocol -ne "http" -and $protocol -ne "https"))
{
$isInputValid = $false
}

return $isInputValid
}

function Download-Files
{
Write-Verbose -Verbose "Downloading makecert.exe and winrmconf.cmd files"

$source="https://azurergtaskstorage.blob.core.windows.net/winrm/makecert.exe"
Invoke-WebRequest $source -OutFile .\makecert.exe -ErrorAction Stop

$source="https://azurergtaskstorage.blob.core.windows.net/winrm/winrmconf.cmd"
Invoke-WebRequest $source -OutFile .\winrmconf.cmd -ErrorAction Stop
}

function Delete-WinRMListener
{
$config = winrm enumerate winrm/config/listener
foreach($conf in $config)
{
if($conf.Contains("HTTPS"))
{
Write-Verbose -Verbose "HTTPS is already configured. Deleting the exisiting configuration."

winrm delete winrm/config/Listener?Address=*+Transport=HTTPS
break
}
}
}

function Configure-WinRMListener
{
param([string] $hostname,
[string] $protocol)

Write-Verbose -Verbose "Configuring the WinRM listener for $hostname over $protocol protocol"

if($protocol -ne "http")
{
Configure-WinRMHttpsListener -hostname $hostname -port $winrmHttpsPort
}
else
{
Configure-WinRMHttpListener
}

Write-Verbose -Verbose "Successfully Configured the WinRM listener for $hostname over $protocol protocol"
}

function Configure-WinRMHttpListener
{
winrm delete winrm/config/Listener?Address=*+Transport=HTTP
winrm create winrm/config/Listener?Address=*+Transport=HTTP
}

function Configure-WinRMHttpsListener
{
param([string] $hostname,
[string] $port)

# Delete the WinRM Https listener if it is already configured
Delete-WinRMListener

# Create a test certificate
$thumbprint = (Get-ChildItem cert:\LocalMachine\My | Where-Object { $_.Subject -eq "CN=" + $hostname } | Select-Object -Last 1).Thumbprint
if(-not $thumbprint)
{
.\makecert -r -pe -n CN=$hostname -b 01/01/2012 -e 01/01/2022 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
$thumbprint=(Get-ChildItem cert:\Localmachine\my | Where-Object { $_.Subject -eq "CN=" + $hostname } | Select-Object -Last 1).Thumbprint

if(-not $thumbprint)
{
throw "Failed to create the test certificate."
}
}

# Configure WinRM
cmd.exe /c .\winrmconf.cmd $hostname $thumbprint
}

function Add-FirewallException
{
param([string] $protocol)

if( $protocol -ne "http")
{
$port = $winrmHttpsPort
}
else
{
$port = $winrmHttpPort
}

# Delete an exisitng rule
Write-Verbose -Verbose "Deleting the existing firewall exception for port $port"
netsh advfirewall firewall delete rule name="Windows Remote Management (HTTPS-In)" dir=in protocol=TCP localport=$port | Out-Null

# Add a new firewall rule
Write-Verbose -Verbose "Adding the firewall exception for port $port"
netsh advfirewall firewall add rule name="Windows Remote Management (HTTPS-In)" dir=in action=allow protocol=TCP localport=$port | Out-Null
}


#################################################################################################################################
# Configure WinRM #
#################################################################################################################################

netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=yes
winrm quickconfig

# The default MaxEnvelopeSizekb on Windows Server is 500 Kb which is very less. It needs to be at 8192 Kb. The small envelop size if not changed
# results in WS-Management service responding with error that the request size exceeded the configured MaxEnvelopeSize quota.
winrm set winrm/config '@{MaxEnvelopeSizekb = "8192"}'

# Validate script arguments
if(-not (Is-InputValid -hostname $hostname))
{
Write-Warning "Invalid Argument exception:"
Write-Host $helpMsg

return
}

# Download files
Download-Files

# Configure WinRM listener
Configure-WinRMListener -hostname $hostname -protocol $protocol

# Add firewall exception
Add-FirewallException -protocol $protocol

# List the listeners
Write-Verbose -Verbose "Listing the WinRM listeners:"
$config = winrm enumerate winrm/config/listener

Write-Verbose -Verbose "Querying WinRM listeners by running command: winrm enumerate winrm/config/listener"
$config

#################################################################################################################################
#################################################################################################################################

108 changes: 108 additions & 0 deletions Tasks/PowerShellOnTargetMachinesV1/PowerShellJob.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
$RunPowershellJob = {
param (
[string]$fqdn,
[string]$scriptPath,
[string]$port,
[string]$scriptArguments,
[string]$initializationScriptPath,
[object]$credential,
[string]$httpProtocolOption,
[string]$skipCACheckOption,
[string]$enableDetailedLogging,
[string]$sessionVariables
)

Write-Verbose "fqdn = $fqdn"
Write-Verbose "scriptPath = $scriptPath"
Write-Verbose "port = $port"
Write-Verbose "scriptArguments = $scriptArguments"
Write-Verbose "initializationScriptPath = $initializationScriptPath"
Write-Verbose "protocolOption = $httpProtocolOption"
Write-Verbose "skipCACheckOption = $skipCACheckOption"
Write-Verbose "enableDetailedLogging = $enableDetailedLogging"

if(Test-Path "$env:AGENT_HOMEDIRECTORY\Agent\Worker")
{
Get-ChildItem $env:AGENT_HOMEDIRECTORY\Agent\Worker\*.dll | % {
[void][reflection.assembly]::LoadFrom( $_.FullName )
Write-Verbose "Loading .NET assembly:`t$($_.name)"
}

Get-ChildItem $env:AGENT_HOMEDIRECTORY\Agent\Worker\Modules\Microsoft.TeamFoundation.DistributedTask.Task.DevTestLabs\*.dll | % {
[void][reflection.assembly]::LoadFrom( $_.FullName )
Write-Verbose "Loading .NET assembly:`t$($_.name)"
}
}
else
{
if(Test-Path "$env:AGENT_HOMEDIRECTORY\externals\vstshost")
{
[void][reflection.assembly]::LoadFrom("$env:AGENT_HOMEDIRECTORY\externals\vstshost\Microsoft.TeamFoundation.DistributedTask.Task.LegacySDK.dll")
}
}

$enableDetailedLoggingOption = ''
if ($enableDetailedLogging -eq "true")
{
$enableDetailedLoggingOption = '-EnableDetailedLogging'
}

$parsedSessionVariables = Get-ParsedSessionVariables -inputSessionVariables $sessionVariables

Write-Verbose "Initiating deployment on $fqdn"
[String]$psOnRemoteScriptBlockString = "Invoke-PsOnRemote -MachineDnsName $fqdn -ScriptPath `$scriptPath -WinRMPort $port -Credential `$credential -ScriptArguments `$scriptArguments -InitializationScriptPath `$initializationScriptPath -SessionVariables `$parsedSessionVariables $skipCACheckOption $httpProtocolOption $enableDetailedLoggingOption"
[scriptblock]$psOnRemoteScriptBlock = [scriptblock]::Create($psOnRemoteScriptBlockString)
$deploymentResponse = Invoke-Command -ScriptBlock $psOnRemoteScriptBlock

# Telemetry data logic through ps session
try{
if($skipCACheckOption)
{
$sessionOption = New-PSSessionOption -SkipCACheck
}
else
{
$sessionOption = New-PSSessionOption
}
$secpasswd = ConvertTo-SecureString $credential.Password -AsPlainText -Force
$psCredential = New-Object System.Management.Automation.PSCredential($credential.UserName, $secpasswd)
if($httpProtocolOption -eq '-UseHttp')
{
$session = New-PSSession -Computer $fqdn -Port $port -Credential $psCredential -SessionOption ($sessionOption )
}
else
{
$session = New-PSSession -Computer $fqdn -Port $port -Credential $psCredential -SessionOption ($sessionOption ) -UseSSL
}
$VmUuidHash = Invoke-Command -Session $session -ScriptBlock {
$sha = New-Object System.Security.Cryptography.SHA512CryptoServiceProvider
$computerDetails = Get-WmiObject -class Win32_ComputerSystemProduct -namespace root\CIMV2
$encoding = [system.Text.Encoding]::ASCII
$uuidHash = [System.BitConverter]::ToString( $sha.ComputeHash($encoding.GetBytes($computerDetails.UUID)))
$uuidHash = $uuidHash -replace "-" , ""
return $uuidHash
}
$isAzureVm = Invoke-Command -Session $session -ScriptBlock {
(Get-Process -Name 'WindowsAzureGuestAgent' -ErrorAction Ignore) | Select-Object -First 1 | ForEach-Object {
if($_.Path)
{
return $true
}
else
{
return $false
}
}
}
$deploymentResponse | Add-Member "IsAzureVm" $IsAzureVm -Force
$deploymentResponse | Add-Member "VmUuidHash" $VmUuidHash -Force
}
catch
{
Write-Verbose "Error during fetching telemetry = $_"
$deploymentResponse | Add-Member "TelemetryError" $_ -Force
}


Write-Output $deploymentResponse
}
Loading