This post should not be needed for your production environment. This is for those of us who test and build development environments at home and have created hybrid environments into Azure. IF you have a dynamic IP address for your business, please spend the extra bit of money for a static IP…
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$false Install-Module -Name MSOnline -AllowClobber -Confirm:$false
Param ( [string]$displayName = "SVC-Nework-Gateway-Updater", [string]$firstName = "Network-Gateway", [string]$lastName = "Updater-Account", [string]$upn = "svc_network-updater@yourDomain.onmicrosoft.com", [string]$password = "MyPassword#12345", [string]$usageLocation = "US" ) $oCred = Get-Credential -Message "Enter Admin Credentials for O365..." Connect-MsolService -Credential $oCred $user = New-MsolUser -DisplayName $displayName ` -FirstName $firstName ` -LastName $lastName ` -UserPrincipalName $upn ` -UsageLocation $usageLocation ` -ForceChangePassword:$false ` -PasswordNeverExpires:$true ` -Password $password
Param ( [string]$subscriptionName = "mySubscription", [string]$resourceGroupName = "Networking", [string]$localGatewayName = "LocalGateway", [string]$userID = "508bb5e1-898e-user-9a71-47de815db2af" ) Login-AzureRmAccount -SubscriptionName $subscriptionName $ID = Get-AzureRmResourceGroup $resourceGroup1 | Get-AzureRmLocalNetworkGateway -Name $localGatewayName | select Id New-AzureRmRoleAssignment -Scope $ID.Id -ObjectId $userID -RoleDefinitionName "Contributor" <# Remove User from EVERYWHERE! Get-AzureRmRoleAssignment | Where-Object {$_.ObjectId -eq $userID} | Remove-AzureRmRoleAssignment #>
With permissions set for Local Network Gateway, it is time to look at the current IP address of the gateway endpoint and compare it to the current local IP address endpoint. If the two IP addresses do not match, it is time to update your Local Network Gateway (in Azure).
Param ( [string]$resourceGroup = "Networking-US-East-2", [string]$localGatewayName = "LocalGateway-HQ", [string]$location = "East US 2", [string]$lgwSubnetPrefix = "192.168.0.0/21" ) function Get-LocalIP { $wc = New-Object net.webclient $localIP = $wc.downloadstring("http://checkip.dyndns.com") -replace "[^\d\.]" return $localIP } function Get-LocalGatewayIP ($resourceGroup, $localGatewayName) { $lng = Get-AzureRmLocalNetworkGateway -Name $localGatewayName -ResourceGroupName $resourceGroup return $lng.GatewayIpAddress } function Update-LocalGateway ($resourceGroup, $localGatewayName, $localIP, $location, $addressPrefix) { $localGateway = New-AzureRmLocalNetworkGateway -Name $localGatewayName ` -ResourceGroupName $resourceGroup ` -Location $location ` -GatewayIpAddress $localIP ` -AddressPrefix $addressPrefix ` -Force ` -Confirm:$false Write-Output("$localGatewayName Local Gateway updated...") } $localIP = Get-LocalIP $gatewayIP = Get-LocalGatewayIP -resourceGroup $resourceGroup -localGatewayName $localGatewayName If ($gatewayIP -ne $localIP) { Update-LocalGateway -resourceGroup $resourceGroup ` -localGatewayName $localGatewayName ` -localIP $localIP ` -location $location ` -addressPrefix $lgwSubnetPrefix }
Next we create some logging and logging clean-up:
function Update-Logs ($content) { $logPath = 'C:\S2S Logs' if (-not (Test-Path -Path $logPath)) {New-Item -Path $logPath -ItemType Directory} $date = Get-Date $lastMonth = $date.AddMonths(-1) $fileName = $date.ToString("yyyy-MM-dd") + "- S2S Log.txt" $filePath = ($logPath + "\" + $fileName) $exists = Test-Path $filePath if ($exists) { $string = (Get-Date).ToShortTimeString().ToString() + " $content" $string | Out-File -FilePath $filePath -Append } if (-not $exists) { $string | Out-File -FilePath $filePath } # Clean Up Logs Older than 1 month $items = Get-ChildItem -Path $logPath -Recurse -Filter *.txt | Where-Object {$_.CreationTime.Date -lt $lastMonth} $items | Remove-Item -Force }
And to finish off, we will connect all of our RRAS VpnS2SInterface connections.
$connections = (Get-VpnS2SInterface).Name foreach ($connection in $connections) { Connect-VpnS2SInterface -Name $connection }
Now let’s put the whole thing together. First we create the service account and add their permissions:
Param ( [string]$msolDisplayName = "SVC-Nework-Gateway-Updater", [string]$msolFirstName = "Network-Gateway", [string]$msolLastName = "Updater-Account", [string]$msolUpn = "svc_network-updater@yourDomain.onmicrosoft.com", [string]$msolPassword = "MyPassword#12345", [string]$msolUsageLocation = "US", [string]$azureSubscriptionName = "mySubscription", [string]$azureResourceGroupName = "Networking", [string]$azureLocalGatewayName = "LocalGateway" ) #region Login to O365 and Create User $cred = Get-Credential -Message "Enter Admin Credentials for O365..." Connect-MsolService -Credential $cred $user = New-MsolUser -DisplayName $msolDisplayName ` -FirstName $msolFirstName ` -LastName $msolLastName ` -UserPrincipalName $msolUpn ` -UsageLocation $msolUsageLocation ` -ForceChangePassword:$false ` -PasswordNeverExpires:$true ` -Password $msolPassword #endregion #region Login to Azure and Add User to Local Network Gateway RBAC Login-AzureRmAccount -SubscriptionName $azureSubscriptionName $ID = Get-AzureRmResourceGroup $azureResourceGroupName | Get-AzureRmLocalNetworkGateway -Name $azureLocalGatewayName | select Id New-AzureRmRoleAssignment -Scope $ID.Id -ObjectId $user.ObjectId -RoleDefinitionName "Contributor" <# Remove User from EVERYWHERE! Get-AzureRmRoleAssignment | Where-Object {$_.ObjectId -eq $userID} | Remove-AzureRmRoleAssignment #> #endregion
Next we create the Update S2S file, and save the file to: ‘C:\Scripts\Update S2S and RRAS.ps1’
Param ( [string]$userName = "svc_network-updater@yourDomain.onmicrosoft.com", [string]$password = "MyPassword#12345", [string]$subscriptionName = "mySubscription", [string]$resourceGroup = "Networking-US-East-2", [string]$localGatewayName = "LocalGateway-HQ", [string]$location = "East US 2", [string]$lgwSubnetPrefix = "192.168.0.0/21" ) #region Login to Azure $securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential($userName, $securePassword) Login-AzureRmAccount -Credential $cred -SubscriptionName $subscriptionName $subscription = (Get-AzureRmSubscription | Where-Object {$_.SubscriptionName -eq $subscriptionName}).SubscriptionId Select-AzureRmSubscription -Subscriptionid $subscription #endregion function Update-Logs ($content) { $logPath = 'C:\S2S Logs' if (-not (Test-Path -Path $logPath)) {New-Item -Path $logPath -ItemType Directory} $date = Get-Date $lastMonth = $date.AddMonths(-1) $fileName = $date.ToString("yyyy-MM-dd") + "- S2S Log.txt" $filePath = ($logPath + "\" + $fileName) $exists = Test-Path $filePath if ($exists) { $string = (Get-Date).ToShortTimeString().ToString() + " $content" $string | Out-File -FilePath $filePath -Append } if (-not $exists) { $string | Out-File -FilePath $filePath } # Clean Up Logs Older than 1 month $items = Get-ChildItem -Path $logPath -Recurse -Filter *.txt | Where-Object {$_.CreationTime.Date -lt $lastMonth} $items | Remove-Item -Force } function Get-LocalIP { $wc = New-Object net.webclient $localIP = $wc.downloadstring("http://checkip.dyndns.com") -replace "[^\d\.]" return $localIP } function Get-LocalGatewayIP ($resourceGroup, $localGatewayName) { $lng = Get-AzureRmLocalNetworkGateway -Name $localGatewayName -ResourceGroupName $resourceGroup return $lng.GatewayIpAddress } function Update-LocalGateway ($resourceGroup, $localGatewayName, $localIP, $location, $addressPrefix) { $localGateway = New-AzureRmLocalNetworkGateway -Name $localGatewayName ` -ResourceGroupName $resourceGroup ` -Location $location ` -GatewayIpAddress $localIP ` -AddressPrefix $addressPrefix ` -Force ` -Confirm:$false Write-Output("$localGatewayName Local Gateway updated...") } function Connect-LocalGateway { $connections = (Get-VpnS2SInterface).Name foreach ($connection in $connections) { Connect-VpnS2SInterface -Name $connection } Update-Logs -content ((Get-VpnS2SInterface).Name.toString() + "-" + (Get-VpnS2SInterface).ConnectionState.toString()) } #region Execute # Get Local IP Address Endpoint $localIP = Get-LocalIP # Get Azure Local Gateway IP Address $gatewayIP = Get-LocalGatewayIP -resourceGroup $resourceGroup -localGatewayName $localGatewayName # Update Log File Update-Logs -content ("Gateway IP = $gatewayIP and Local IP = $localIP") # If IP Addresses don't match update Azure Local Gateway IP Address If ($gatewayIP -ne $localIP) { Update-LocalGateway -resourceGroup $resourceGroup ` -localGatewayName $localGatewayName ` -localIP $localIP ` -location $location ` -addressPrefix $lgwSubnetPrefix Update-Logs -content ("Azure Local Gateway Updated") } # Make sure all RRAS connections are connected. Connect-LocalGateway #endregion
#region Create Scheduled Task as User $jobName = "Azure S2S IP Checker" $filePath = 'C:\Scripts\Update S2S and RRAS.ps1' $cred = Get-Credential -Message "Enter Run As Credentials..." $sj = Get-ScheduledJob -Name $jobName -ErrorAction SilentlyContinue if ($sj.count -gt 0) { Write-Host "$jobName scheduled job already exists..." } else { Write-Host "Creating $jobName scheduled Job..." $sj = Register-ScheduledJob –Name $jobName ` -Credential $cred ` -FilePath $filePath ` -ScheduledJobOption (New-ScheduledJobOption -ContinueIfGoingOnBattery:$true -StartIfOnBattery:$true) ` -Trigger (New-JobTrigger -Once -At "12/12/2017 01:00:00" -RepetitionInterval (New-TimeSpan -Hours 1) -RepeatIndefinitely) } #endregion
About the Author:
I am currently the Director for the Federal Group and a SharePoint Architect for Planet Technologies. I have been working with SharePoint since 2003 doing everything from administration, branding, and development to upgrading, and troubleshooting. I work with clients, all over the world, to help integrate their organization into SharePoint. I have a very diverse background, and bring a lot of experience and insight into infrastructure and troubleshooting. I have designed and deployed many farms of varying complexity over the years, especially within the Federal realm where nothing is small or simple. I am a co-author of Microsoft® SharePoint® 2013: Designing and Architecting Solutions for Microsoft Press. MCT, MCTS, MCP, MCITP, MCPD, MCSA, MCSE
Reference:
Curran, P. (2017). How to Maintain an Azure Site-to-Site (S2S) Connection with a Dynamic IP Address. Available at: http://blog.pcfromdc.com/2017/12/how-to-maintain-azure-site-to-site-s2s.html [Accessed 15th November 2018]