|
| 1 | +--- |
| 2 | +title: Manage remote on-premises resources using PowerShell Azure Functions |
| 3 | +description: Learn how to configure Hybrid Connections in Azure Relay to connect a PowerShell function app to on-premises resources, which can then be used to remotely manage the on-premises resource. |
| 4 | +author: eamono |
| 5 | +manager: gailey777 |
| 6 | + |
| 7 | +ms.service: azure-functions |
| 8 | +ms.topic: conceptual |
| 9 | +ms.date: 9/5/2019 |
| 10 | +ms.author: eamono |
| 11 | +# Customer intent: As solution architect, I want to be able to connect my function app in Azure to on-premises resources so I can remotely manage those resources by using PowerShell functions. |
| 12 | +--- |
| 13 | + |
| 14 | +# Managing hybrid environments with PowerShell in Azure Functions and App Service Hybrid Connections |
| 15 | + |
| 16 | +The Azure App Service Hybrid Connections enables access to resources in other networks. You can learn more about this capability on the [Hybrid Connections](../app-service/app-service-hybrid-connections.md) documentation. The following information describes how to use this capability to run PowerShell functions targeting an on-premises server. This server can then be used to manage all resources within the on-premises environment from an Azure PowerShell function. |
| 17 | + |
| 18 | + |
| 19 | +## Configure an on-premises server for PowerShell remoting |
| 20 | + |
| 21 | +The below script enables PowerShell remoting, creates a new firewall rule, and a WinRM https listener. For testing purposes, a self-signed cert is used. It is recommended to use a signed certificate for production. |
| 22 | + |
| 23 | +```powershell |
| 24 | +# For configuration of WinRM, please see |
| 25 | +# https://docs.microsoft.com/windows/win32/winrm/installation-and-configuration-for-windows-remote-management |
| 26 | +
|
| 27 | +# Enable PowerShell remoting |
| 28 | +Enable-PSRemoting -Force |
| 29 | +
|
| 30 | +# Create firewall rule for WinRM. The default HTTPS port is 5986 |
| 31 | +New-NetFirewallRule -Name "WinRM HTTPS" ` |
| 32 | + -DisplayName "WinRM HTTPS" ` |
| 33 | + -Enabled True ` |
| 34 | + -Profile "Any" ` |
| 35 | + -Action "Allow" ` |
| 36 | + -Direction "Inbound" ` |
| 37 | + -LocalPort 5986 ` |
| 38 | + -Protocol "TCP" |
| 39 | +
|
| 40 | +# Create new self-signed-certificate to be used by WinRM |
| 41 | +$Thumbprint = (New-SelfSignedCertificate -DnsName $env:COMPUTERNAME -CertStoreLocation Cert:\LocalMachine\My).Thumbprint |
| 42 | +
|
| 43 | +# Create WinRM HTTPS listener |
| 44 | +$Cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname=""$env:COMPUTERNAME ""; CertificateThumbprint=""$Thumbprint""}" |
| 45 | +cmd.exe /C $Cmd |
| 46 | +``` |
| 47 | + |
| 48 | +## Create a PowerShell function app in the portal |
| 49 | + |
| 50 | +App Service Hybrid Connections are only available in Basic, Standard, and Isolated pricing plans. When creating the function app with PowerShell, create or select one of these plans. |
| 51 | + |
| 52 | +1. Go to the [Azure portal](https://portal.azure.com). |
| 53 | + |
| 54 | +1. Select **+ Create a resource** on the left hand side, then choose **Function app**. |
| 55 | + |
| 56 | +1. For **Hosting plan**, choose **App Service plan**, then select **App Service plan/Location**. |
| 57 | + |
| 58 | +1. Select **Create new**, type an **App Service plan** name, choose a **Location** in a [region](https://azure.microsoft.com/regions/) near you or near other services your functions access, and then select **Pricing tier**. |
| 59 | + |
| 60 | +1. Choose the S1 Standard plan, then select **Apply**. |
| 61 | + |
| 62 | +1. Select **OK** to create the plan, then use the remaining function app settings as specified in the table below the image. |
| 63 | + |
| 64 | +  |
| 65 | + |
| 66 | + | Setting | Suggested value | Description | |
| 67 | + | ------------ | ------- | -------------------------------------------------- | |
| 68 | + | **App name** | Globally unique name | Name that identifies your new function app. Valid characters are `a-z`, `0-9`, and `-`. | |
| 69 | + | **Subscription** | Your subscription | The subscription under which this new function app is created. | |
| 70 | + | **Resource Group** | myResourceGroup | Name for the new resource group in which to create your function app. You can also use the suggested value. | |
| 71 | + | **OS** | Preferred OS | Select Windows. | |
| 72 | + | **Runtime stack** | Preferred language | Choose PowerShell Core. | |
| 73 | + | **Storage** | Globally unique name | Create a storage account used by your function app. Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only. You can also use an existing account. |
| 74 | + | **Application Insights** | Default | Creates an Application Insights resource of the same *App name* in the nearest supported region. By expanding this setting, you can change the **New resource name** or choose a different **Location** in an [Azure geography](https://azure.microsoft.com/global-infrastructure/geographies/) where you want to store your data. | |
| 75 | + |
| 76 | +1. After your settings are validated, select **Create**. |
| 77 | + |
| 78 | +1. Select the Notification icon in the upper-right corner of the portal and watch for the **Deployment succeeded** message. |
| 79 | + |
| 80 | +1. Select **Go to resource** to view your new function app. You can also select **Pin to dashboard**. Pinning makes it easier to return to this function app resource from your dashboard. |
| 81 | + |
| 82 | +## Create a hybrid connection for the function app |
| 83 | + |
| 84 | +Hybrid connections are configured from the networking section of the function app. |
| 85 | + |
| 86 | +1. Select the platform tab of the function app and select networking. |
| 87 | + |
| 88 | +1. Select Configure your hybrid connections endpoints. |
| 89 | + |
| 90 | +1. Select Add hybrid connection. |
| 91 | + |
| 92 | +1. Enter information about for the hybrid connection as shown below. The Endpoint Host can optionally match the hostname of the on-premises server to make it easier to remember the server later when running remote commands. The port matches the default Windows remote management service port defined on the server earlier. |
| 93 | + |
| 94 | + |
| 95 | + **Hybrid connection name** ContosoHybridOnPremisesServer |
| 96 | + |
| 97 | + **Endpoint Host** finance1 |
| 98 | + |
| 99 | + **Endpoint Port** 5986 |
| 100 | + |
| 101 | + **Servicebus namespace** Create New |
| 102 | + |
| 103 | + **Location** Pick an available location |
| 104 | + |
| 105 | + **Name** contosopowershellhybrid |
| 106 | + |
| 107 | +5. Click OK to create the hybrid connection |
| 108 | + |
| 109 | +## Download and install the hybrid connection |
| 110 | + |
| 111 | +1. Select the Download connection manager icon to save the .msi file locally on your computer. |
| 112 | + |
| 113 | +1. Copy the .msi from your local computer to the on-premises server. |
| 114 | +1. Run the hybrid connection installer to install the service on the on-premises server. |
| 115 | + |
| 116 | +1. From the portal, open the hybrid connection and copy the gateway connection string to the clipboard. |
| 117 | + |
| 118 | +1. Open the Hybrid Connection Manager UI on the on-premises server. |
| 119 | + |
| 120 | +1. Select the "Enter Manually" button and paste the connection string from the clipboard. |
| 121 | + |
| 122 | +1. Restart the hybrid connection manager from PowerShell if it does not show connected. |
| 123 | +```powershell |
| 124 | +Restart-Service HybridConnectionManager |
| 125 | +``` |
| 126 | + |
| 127 | +## Create an app setting for the password of an administrator account |
| 128 | + |
| 129 | +1. Select the Platform tab from the function application |
| 130 | +1. Select the Configuration from the General Settings section |
| 131 | + |
| 132 | +1. Select New application setting to create a new setting for the password |
| 133 | +1. Name the setting ContosoUserPassword and enter the password |
| 134 | +1. Select OK and then Save to store the password in the function application |
| 135 | + |
| 136 | + |
| 137 | +## Create a function http trigger to test |
| 138 | + |
| 139 | +1. Create a new http trigger function from the function app |
| 140 | + |
| 141 | +1. Replace the PowerShell code from the template with the following code: |
| 142 | + |
| 143 | + ```powershell |
| 144 | + # Input bindings are passed in via param block. |
| 145 | + param($Request, $TriggerMetadata) |
| 146 | + |
| 147 | + # Write to the Azure Functions log stream. |
| 148 | + Write-Output "PowerShell HTTP trigger function processed a request." |
| 149 | + |
| 150 | + # Note that ContosoUserPassword is a function app setting, so I can access it as $env:ContosoUserPassword |
| 151 | + $UserName = "ContosoUser" |
| 152 | + $securedPassword = ConvertTo-SecureString $Env:ContosoUserPassword -AsPlainText -Force |
| 153 | + $Credential = [System.management.automation.pscredential]::new($UserName, $SecuredPassword) |
| 154 | + |
| 155 | + # This is the name of the hybrid connection Endpoint. |
| 156 | + $HybridEndpoint = "finance1" |
| 157 | + |
| 158 | + $Script = { |
| 159 | + Param( |
| 160 | + [Parameter(Mandatory=$True)] |
| 161 | + [String] $Service |
| 162 | + ) |
| 163 | + Get-Service $Service |
| 164 | + } |
| 165 | + |
| 166 | + Write-Output "Scenario 1: Running command via Invoke-Command" |
| 167 | + Invoke-Command -ComputerName $HybridEndpoint ` |
| 168 | + -Credential $Credential ` |
| 169 | + -Port 5986 ` |
| 170 | + -UseSSL ` |
| 171 | + -ScriptBlock $Script ` |
| 172 | + -ArgumentList "*" ` |
| 173 | + -SessionOption (New-PSSessionOption -SkipCACheck) |
| 174 | + ``` |
| 175 | +
|
| 176 | +3. Click Save and run to test the function |
| 177 | + |
| 178 | +
|
| 179 | +## Managing other systems on-premises |
| 180 | +
|
| 181 | +You can use the connected on-premises server to connect to other servers and management systems in the local environment. This lets you manage your data center operations from Azure using your PowerShell functions. The following script registers a PowerShell configuration session that runs under the supplied credentials. These credentials need to be an administrator on the remote servers. You can then use this configuration to access other endpoints in the local server or data center. |
| 182 | +
|
| 183 | +```powershell |
| 184 | +# Input bindings are passed in via param block. |
| 185 | +param($Request, $TriggerMetadata) |
| 186 | +
|
| 187 | +# Write to the Azure Functions log stream. |
| 188 | +Write-Host "PowerShell HTTP trigger function processed a request." |
| 189 | +
|
| 190 | +# Note that ContosoUserPassword is a function app setting, so I can access it as $env:ContosoUserPassword |
| 191 | +$UserName = "ContosoUser" |
| 192 | +$SecuredPassword = ConvertTo-SecureString $Env:ContosoUserPassword -AsPlainText -Force |
| 193 | +$Credential = [System.management.automation.pscredential]::new($UserName, $SecuredPassword) |
| 194 | +
|
| 195 | +# This is the name of the hybrid connection Endpoint. |
| 196 | +$HybridEndpoint = "finance1" |
| 197 | +
|
| 198 | +# The remote server that will be conected to run remote PowerShell commands on |
| 199 | +$RemoteServer = "finance2" |
| 200 | +
|
| 201 | +Write-Output "Use hybrid connection server as a jump box to connect to a remote machine" |
| 202 | +
|
| 203 | +# We are registering an endpoint that runs under credentials ($Credential) that has access to the remote server. |
| 204 | +$SessionName = "HybridSession" |
| 205 | +$ScriptCommand = { |
| 206 | + param ( |
| 207 | + [Parameter(Mandatory=$True)] |
| 208 | + $SessionName) |
| 209 | +
|
| 210 | + if (-not (Get-PSSessionConfiguration -Name $SessionName -ErrorAction SilentlyContinue)) |
| 211 | + { |
| 212 | + Register-PSSessionConfiguration -Name $SessionName -RunAsCredential $Using:Credential |
| 213 | + } |
| 214 | +} |
| 215 | +
|
| 216 | +Write-Output "Registering session on hybrid connection jumpbox" |
| 217 | +Invoke-Command -ComputerName $HybridEndpoint ` |
| 218 | + -Credential $Credential ` |
| 219 | + -Port 5986 ` |
| 220 | + -UseSSL ` |
| 221 | + -ScriptBlock $ScriptCommand ` |
| 222 | + -ArgumentList $SessionName ` |
| 223 | + -SessionOption (New-PSSessionOption -SkipCACheck) |
| 224 | +
|
| 225 | +# Script to run on the jump box to run against the second machine |
| 226 | +$RemoteScriptCommand = { |
| 227 | + param ( |
| 228 | + [Parameter(Mandatory=$True)] |
| 229 | + $ComputerName) |
| 230 | + # Write out the hostname of the hybrid connection server |
| 231 | + hostname |
| 232 | + # Write out the hostname of the remote server |
| 233 | + Invoke-Command -ComputerName $ComputerName -Credential $Using:Credential -ScriptBlock {hostname} ` |
| 234 | + -UseSSL -Port 5986 -SessionOption (New-PSSessionOption -SkipCACheck) |
| 235 | +} |
| 236 | +
|
| 237 | +Write-Output "Running command against remote machine via jumpbox by connecting to the PowerShell configuration session" |
| 238 | +Invoke-Command -ComputerName $HybridEndpoint ` |
| 239 | + -Credential $Credential ` |
| 240 | + -Port 5986 ` |
| 241 | + -UseSSL ` |
| 242 | + -ScriptBlock $RemoteScriptCommand ` |
| 243 | + -ArgumentList $RemoteServer ` |
| 244 | + -SessionOption (New-PSSessionOption -SkipCACheck) ` |
| 245 | + -ConfigurationName $SessionName |
| 246 | +``` |
| 247 | + |
| 248 | +Replace these variables in the above script with the values you have in your environment: |
| 249 | +* $HybridEndpoint |
| 250 | +* $RemoteServer |
| 251 | + |
| 252 | +The above two scenarios enable you to connect and manage your on-premises environments using PowerShell in Azure Functions and Hybrid Connections. You can learn additional information on [Hybrid Connections](../app-service/app-service-hybrid-connections.md) or [PowerShell in functions](./functions-reference-powershell.md) in the documentation. |
| 253 | + |
| 254 | +You can also use Azure [virtual networks](./functions-create-vnet.md) to connect to your on-premises environment using Azure Functions. |
| 255 | + |
| 256 | +## Next steps |
| 257 | + |
| 258 | +> [!div class="nextstepaction"] |
| 259 | +> [Learn more about working with PowerShell functions](functions-reference-powershell.md) |
0 commit comments