diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index bec457a835289dafde8684a3a540feff0703a8aa..bbc6fcecb68e3eb7fd8753b7239cbaeaa12cc676 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -392,17 +392,17 @@
       <Uri>https://github.com/aspnet/Extensions</Uri>
       <Sha>bfea1edf9e2e9a5465f331517149c4f543ac2ba6</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19274.6">
+    <Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19302.2">
       <Uri>https://github.com/dotnet/arcade</Uri>
-      <Sha>b5016f5688dc8ca9f3e4811ee7e2e86ad8907a40</Sha>
+      <Sha>e6a5d5f970bb872451c6310ae34eda31041fb552</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19274.6">
+    <Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19302.2">
       <Uri>https://github.com/dotnet/arcade</Uri>
-      <Sha>b5016f5688dc8ca9f3e4811ee7e2e86ad8907a40</Sha>
+      <Sha>e6a5d5f970bb872451c6310ae34eda31041fb552</Sha>
     </Dependency>
-    <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19274.6">
+    <Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="2.0.0-beta.19302.2">
       <Uri>https://github.com/dotnet/arcade</Uri>
-      <Sha>b5016f5688dc8ca9f3e4811ee7e2e86ad8907a40</Sha>
+      <Sha>e6a5d5f970bb872451c6310ae34eda31041fb552</Sha>
     </Dependency>
     <Dependency Name="Microsoft.AspNetCore.Testing" Version="3.0.0-preview6.19280.1" CoherentParentDependency="Microsoft.CodeAnalysis.Razor">
       <Uri>https://github.com/aspnet/Extensions</Uri>
diff --git a/eng/Versions.props b/eng/Versions.props
index 82cc9dd8d349ecb5f1c8487851b13f1f347cadba..3c04e9189566112bfb1e3742edb3338a6f14a438 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -21,7 +21,7 @@
   -->
   <PropertyGroup Label="Automated">
     <!-- Packages from dotnet/arcade -->
-    <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19274.6</MicrosoftDotNetGenAPIPackageVersion>
+    <MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19302.2</MicrosoftDotNetGenAPIPackageVersion>
     <!-- Packages from dotnet/core-setup -->
     <MicrosoftExtensionsDependencyModelPackageVersion>3.0.0-preview6-27730-01</MicrosoftExtensionsDependencyModelPackageVersion>
     <MicrosoftNETCoreAppPackageVersion>3.0.0-preview6-27730-01</MicrosoftNETCoreAppPackageVersion>
diff --git a/eng/common/LoggingCommandFunctions.ps1 b/eng/common/LoggingCommandFunctions.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..c225eaecbf25d9fa8749e7d9c0d50f8b2525451f
--- /dev/null
+++ b/eng/common/LoggingCommandFunctions.ps1
@@ -0,0 +1,146 @@
+# Source for this file was taken from https://github.com/microsoft/azure-pipelines-task-lib/blob/11c9439d4af17e6475d9fe058e6b2e03914d17e6/powershell/VstsTaskSdk/LoggingCommandFunctions.ps1
+
+# NOTE: You should not be calling these method directly as they are likely to change.  Instead you should be calling the Write-Pipeline* functions defined in tools.ps1
+
+$script:loggingCommandPrefix = '##vso['
+$script:loggingCommandEscapeMappings = @( # TODO: WHAT ABOUT "="? WHAT ABOUT "%"?
+    New-Object psobject -Property @{ Token = ';' ; Replacement = '%3B' }
+    New-Object psobject -Property @{ Token = "`r" ; Replacement = '%0D' }
+    New-Object psobject -Property @{ Token = "`n" ; Replacement = '%0A' }
+    New-Object psobject -Property @{ Token = "]" ; Replacement = '%5D' }
+)
+# TODO: BUG: Escape % ???
+# TODO: Add test to verify don't need to escape "=".
+
+<########################################
+# Private functions.
+########################################>
+function Format-LoggingCommandData {
+    [CmdletBinding()]
+    param([string]$Value, [switch]$Reverse)
+
+    if (!$Value) {
+        return ''
+    }
+
+    if (!$Reverse) {
+        foreach ($mapping in $script:loggingCommandEscapeMappings) {
+            $Value = $Value.Replace($mapping.Token, $mapping.Replacement)
+        }
+    } else {
+        for ($i = $script:loggingCommandEscapeMappings.Length - 1 ; $i -ge 0 ; $i--) {
+            $mapping = $script:loggingCommandEscapeMappings[$i]
+            $Value = $Value.Replace($mapping.Replacement, $mapping.Token)
+        }
+    }
+
+    return $Value
+}
+
+function Format-LoggingCommand {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory = $true)]
+        [string]$Area,
+        [Parameter(Mandatory = $true)]
+        [string]$Event,
+        [string]$Data,
+        [hashtable]$Properties)
+
+    # Append the preamble.
+    [System.Text.StringBuilder]$sb = New-Object -TypeName System.Text.StringBuilder
+    $null = $sb.Append($script:loggingCommandPrefix).Append($Area).Append('.').Append($Event)
+
+    # Append the properties.
+    if ($Properties) {
+        $first = $true
+        foreach ($key in $Properties.Keys) {
+            [string]$value = Format-LoggingCommandData $Properties[$key]
+            if ($value) {
+                if ($first) {
+                    $null = $sb.Append(' ')
+                    $first = $false
+                } else {
+                    $null = $sb.Append(';')
+                }
+
+                $null = $sb.Append("$key=$value")
+            }
+        }
+    }
+
+    # Append the tail and output the value.
+    $Data = Format-LoggingCommandData $Data
+    $sb.Append(']').Append($Data).ToString()
+}
+
+function Write-LoggingCommand {
+    [CmdletBinding(DefaultParameterSetName = 'Parameters')]
+    param(
+        [Parameter(Mandatory = $true, ParameterSetName = 'Parameters')]
+        [string]$Area,
+        [Parameter(Mandatory = $true, ParameterSetName = 'Parameters')]
+        [string]$Event,
+        [Parameter(ParameterSetName = 'Parameters')]
+        [string]$Data,
+        [Parameter(ParameterSetName = 'Parameters')]
+        [hashtable]$Properties,
+        [Parameter(Mandatory = $true, ParameterSetName = 'Object')]
+        $Command,
+        [switch]$AsOutput)
+
+    if ($PSCmdlet.ParameterSetName -eq 'Object') {
+        Write-LoggingCommand -Area $Command.Area -Event $Command.Event -Data $Command.Data -Properties $Command.Properties -AsOutput:$AsOutput
+        return
+    }
+
+    $command = Format-LoggingCommand -Area $Area -Event $Event -Data $Data -Properties $Properties
+    if ($AsOutput) {
+        $command
+    } else {
+        Write-Host $command
+    }
+}
+
+function Write-LogIssue {
+    [CmdletBinding()]
+    param(
+        [ValidateSet('warning', 'error')]
+        [Parameter(Mandatory = $true)]
+        [string]$Type,
+        [string]$Message,
+        [string]$ErrCode,
+        [string]$SourcePath,
+        [string]$LineNumber,
+        [string]$ColumnNumber,
+        [switch]$AsOutput)
+
+    $command = Format-LoggingCommand -Area 'task' -Event 'logissue' -Data $Message -Properties @{
+            'type' = $Type
+            'code' = $ErrCode
+            'sourcepath' = $SourcePath
+            'linenumber' = $LineNumber
+            'columnnumber' = $ColumnNumber
+        }
+    if ($AsOutput) {
+        return $command
+    }
+
+    if ($Type -eq 'error') {
+        $foregroundColor = $host.PrivateData.ErrorForegroundColor
+        $backgroundColor = $host.PrivateData.ErrorBackgroundColor
+        if ($foregroundColor -isnot [System.ConsoleColor] -or $backgroundColor -isnot [System.ConsoleColor]) {
+            $foregroundColor = [System.ConsoleColor]::Red
+            $backgroundColor = [System.ConsoleColor]::Black
+        }
+    } else {
+        $foregroundColor = $host.PrivateData.WarningForegroundColor
+        $backgroundColor = $host.PrivateData.WarningBackgroundColor
+        if ($foregroundColor -isnot [System.ConsoleColor] -or $backgroundColor -isnot [System.ConsoleColor]) {
+            $foregroundColor = [System.ConsoleColor]::Yellow
+            $backgroundColor = [System.ConsoleColor]::Black
+        }
+    }
+
+    Write-Host $command -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor
+}
\ No newline at end of file
diff --git a/eng/common/build.ps1 b/eng/common/build.ps1
index 67046a43f8c446d568ebafe02cab7a4a0b5b76ab..4cb2ce489b6c83428adad0a26621c30ba6631f4c 100644
--- a/eng/common/build.ps1
+++ b/eng/common/build.ps1
@@ -133,9 +133,8 @@ try {
   Build
 }
 catch {
-  Write-Host $_
-  Write-Host $_.Exception
   Write-Host $_.ScriptStackTrace
+  Write-PipelineTaskError -Message $_
   ExitWithExitCode 1
 }
 
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 9cea610a27f58cdc9ec84bd39b4c0df22f570597..3983d719be3fc47046c8b86ade6059fa76d72631 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -92,6 +92,68 @@ function Exec-Process([string]$command, [string]$commandArgs) {
   }
 }
 
+function Write-PipelineTaskError {
+  [CmdletBinding()]
+  param(
+    [Parameter(Mandatory = $true)]
+    [string]$Message,
+    [Parameter(Mandatory = $false)]
+    [string]$Type = 'error',
+    [string]$ErrCode,
+    [string]$SourcePath,
+    [string]$LineNumber,
+    [string]$ColumnNumber,
+    [switch]$AsOutput)
+
+    if(!$ci) {
+      if($Type -eq 'error') {
+        Write-Error $Message
+        return
+      }
+      elseif ($Type -eq 'warning') {
+        Write-Warning $Message
+        return
+      }
+    }
+
+    if(($Type -ne 'error') -and ($Type -ne 'warning')) {
+      Write-Host $Message
+      return
+    }
+    if(-not $PSBoundParameters.ContainsKey('Type')) {
+      $PSBoundParameters.Add('Type', 'error')
+    }
+    Write-LogIssue @PSBoundParameters
+}
+
+function Write-PipelineSetVariable {
+  [CmdletBinding()]
+  param(
+    [Parameter(Mandatory = $true)]
+    [string]$Name,
+    [string]$Value,
+    [switch]$Secret,
+    [switch]$AsOutput)
+
+    if($ci) {
+      Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $Value -Properties @{
+        'variable' = $Name
+        'issecret' = $Secret
+      } -AsOutput:$AsOutput
+    }
+}
+
+function Write-PipelinePrependPath {
+  [CmdletBinding()]
+  param(
+    [Parameter(Mandatory=$true)]
+    [string]$Path,
+    [switch]$AsOutput)
+    if($ci) {
+      Write-LoggingCommand -Area 'task' -Event 'prependpath' -Data $Path -AsOutput:$AsOutput
+    }
+}
+
 function InitializeDotNetCli([bool]$install) {
   if (Test-Path variable:global:_DotNetInstallDir) {
     return $global:_DotNetInstallDir
@@ -134,7 +196,7 @@ function InitializeDotNetCli([bool]$install) {
       if ($install) {
         InstallDotNetSdk $dotnetRoot $dotnetSdkVersion
       } else {
-        Write-Host "Unable to find dotnet with SDK version '$dotnetSdkVersion'" -ForegroundColor Red
+        Write-PipelineTaskError "Unable to find dotnet with SDK version '$dotnetSdkVersion'"
         ExitWithExitCode 1
       }
     }
@@ -147,12 +209,10 @@ function InitializeDotNetCli([bool]$install) {
   # It also ensures that VS msbuild will use the downloaded sdk targets.
   $env:PATH = "$dotnetRoot;$env:PATH"
 
-  if ($ci) {
-    # Make Sure that our bootstrapped dotnet cli is avaliable in future steps of the Azure Pipelines build
-    Write-Host "##vso[task.prependpath]$dotnetRoot"
-    Write-Host "##vso[task.setvariable variable=DOTNET_MULTILEVEL_LOOKUP]0"
-    Write-Host "##vso[task.setvariable variable=DOTNET_SKIP_FIRST_TIME_EXPERIENCE]1"
-  }
+  # Make Sure that our bootstrapped dotnet cli is avaliable in future steps of the Azure Pipelines build
+  Write-PipelinePrependPath -Path $dotnetRoot
+  Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0'
+  Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1'
 
   return $global:_DotNetInstallDir = $dotnetRoot
 }
@@ -184,7 +244,7 @@ function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $archit
 
   & $installScript @installParameters
   if ($lastExitCode -ne 0) {
-    Write-Host "Failed to install dotnet cli (exit code '$lastExitCode')." -ForegroundColor Red
+    Write-PipelineTaskError -Message "Failed to install dotnet cli (exit code '$lastExitCode')."
     ExitWithExitCode $lastExitCode
   }
 }
@@ -358,7 +418,7 @@ function InitializeBuildTool() {
 
   if ($msbuildEngine -eq "dotnet") {
     if (!$dotnetRoot) {
-      Write-Host "/global.json must specify 'tools.dotnet'." -ForegroundColor Red
+      Write-PipelineTaskError "/global.json must specify 'tools.dotnet'."
       ExitWithExitCode 1
     }
 
@@ -367,13 +427,13 @@ function InitializeBuildTool() {
     try {
       $msbuildPath = InitializeVisualStudioMSBuild -install:$restore
     } catch {
-      Write-Host $_ -ForegroundColor Red
+      Write-PipelineTaskError $_
       ExitWithExitCode 1
     }
 
     $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "net472" }
   } else {
-    Write-Host "Unexpected value of -msbuildEngine: '$msbuildEngine'." -ForegroundColor Red
+    Write-PipelineTaskError "Unexpected value of -msbuildEngine: '$msbuildEngine'."
     ExitWithExitCode 1
   }
 
@@ -390,7 +450,7 @@ function GetDefaultMSBuildEngine() {
     return "dotnet"
   }
 
-  Write-Host "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'." -ForegroundColor Red
+  Write-PipelineTaskError "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'."
   ExitWithExitCode 1
 }
 
@@ -441,7 +501,7 @@ function InitializeToolset() {
   }
 
   if (-not $restore) {
-    Write-Host "Toolset version $toolsetVersion has not been restored." -ForegroundColor Red
+    Write-PipelineTaskError "Toolset version $toolsetVersion has not been restored."
     ExitWithExitCode 1
   }
 
@@ -526,7 +586,7 @@ function MSBuild-Core() {
   $exitCode = Exec-Process $buildTool.Path $cmdArgs
 
   if ($exitCode -ne 0) {
-    Write-Host "Build failed." -ForegroundColor Red
+    Write-PipelineTaskError "Build failed."
 
     $buildLog = GetMSBuildBinaryLogCommandLineArgument $args
     if ($buildLog -ne $null) {      
@@ -554,6 +614,8 @@ function GetMSBuildBinaryLogCommandLineArgument($arguments) {
   return $null
 }
 
+. $PSScriptRoot\LoggingCommandFunctions.ps1
+
 $RepoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..")
 $EngRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
 $ArtifactsDir = Join-Path $RepoRoot "artifacts"
@@ -569,11 +631,8 @@ Create-Directory $ToolsetDir
 Create-Directory $TempDir
 Create-Directory $LogDir
 
-if ($ci) {
-  Write-Host "##vso[task.setvariable variable=Artifacts]$ArtifactsDir"
-  Write-Host "##vso[task.setvariable variable=Artifacts.Toolset]$ToolsetDir"
-  Write-Host "##vso[task.setvariable variable=Artifacts.Log]$LogDir"
-
-  $env:TEMP = $TempDir
-  $env:TMP = $TempDir
-}
+Write-PipelineSetVariable -Name 'Artifacts' -Value $ArtifactsDir
+Write-PipelineSetVariable -Name 'Artifacts.Toolset' -Value $ToolsetDir
+Write-PipelineSetVariable -Name 'Artifacts.Log' -Value $LogDir
+Write-PipelineSetVariable -Name 'TEMP' -Value $TempDir
+Write-PipelineSetVariable -Name 'TMP' -Value $TempDir
diff --git a/global.json b/global.json
index 11a7eb5a26ddbad51f4745aa24b6158d0cb18a07..97f7c9313f72dbd7e959cc1d3ae08b4fffdb5ada 100644
--- a/global.json
+++ b/global.json
@@ -8,7 +8,7 @@
   },
   "msbuild-sdks": {
     "Yarn.MSBuild": "1.15.2",
-    "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19274.6",
-    "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19274.6"
+    "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19302.2",
+    "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19302.2"
   }
 }