script to check forward - migration

I recently made the mailbox migration from workspace to office 365.
Forward was applied using the following script:
#Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName
#-ShowBanner:$false -ExchangeEnvironmentName ] [-DelegatedOrganization ] [-PSSessionOption $ProxyOptions]
$users = Get-Mailbox | Where-Object {$_.EmailAddresses -like '#o365.contoso.com.br'}
foreach ($user in $users)
{
$forward = $user.Alias + "#gsuite.contoso.com.br"
Write-Host $user.Alias, ' --> ', $forward
Set-Mailbox -Identity $user.PrimarySmtpAddress -ForwardingSmtpAddress $forward -DeliverToMailboxAndForward $true
#Set-ADUser -Identity $user.SamAccountName -Add #{proxyAddresses=$proxy}
The migration finished and everything went well.
Some forwards were already disabled during the migration.
But does anyone have a powershell script to check if there are still any forwards active?
As you have many accounts, checking one by one would not be feasible.

Related

NSG Rule Automation Powershell

I'm trying to automate my NSG rules and find out wrong nsg rules. here I'm trying to find the source Ip address is added or not but the code getting executed and deleting the rules even if the IP addresses are available.
$nsg = Get-AzNetworkSecurityGroup -ResourceGroupName Testingday4
$nsgRules = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $nsg
foreach($nsgRule in $nsgRules)
{
if($nsgRule.Direction -eq "inbound" -and {$_.DestinationPortRange -eq -split ('') -or $_.DestinationAddressPrefix -ne $null}){
$nsgRule.Name
Remove-AzNetworkSecurityRuleConfig -Name $nsgRule.Name -NetworkSecurityGroup $nsg
} }
$nsg | Set-AzNetworkSecurityGroup
I tried to reproduce in my environment to delete the rule which haves source address prefix of value for example "10.0.0.0/24".
I could remove that NSG rule successfully using below Power Shell Script
Run below script to delete the specific source IP prefix
Get-AzSubscription
Set-AzContext -SubscriptionId "Subscription ID"
$RGname="Resource Group Name"
$nsgname="NSG Name"
$nsg = Get-AzNetworkSecurityGroup -Name $nsgname -ResourceGroupName $RGname
$nsgRules = Get-AzNetworkSecurityGroup -Name $nsgname -ResourceGroupName $RGname
#$ruleNames = $nsgRules.SecurityRules.Name
#$rulesrcaddpre = $nsgRules.SecurityRules.SourceAddressPrefix
foreach($rule in $nsgRules)
{
$rname = $rule.SecurityRules.Name
$raddpre = $rule.SecurityRules.SourceAddressPrefix
if($raddpre -eq "10.0.0.0/24")
{
#AzNetworkSecurityRuleConfig -Name AllowInternetOutBound
Remove-AzNetworkSecurityRuleConfig -Name $rname -NetworkSecurityGroup $nsg
}
}
$nsg | Set-AzNetworkSecurityGroup
Rule got delete after the execute the script.
In order to create the rule with PowerShell use below Script
# Add the inbound security rule.
$nsg | Add-AzNetworkSecurityRuleConfig -Name $rulename -Description "Allow app port" -Access Allow `
-Protocol * -Direction Inbound -Priority 3891 -SourceAddressPrefix "*" -SourcePortRange * `
-DestinationAddressPrefix * -DestinationPortRange $port
# Update the NSG.
$nsg | Set-AzNetworkSecurityGroup

Azure automation runbook Completed before running the code

I have a situation where in the Azure automation runbook results in 'Completed' state and does not run the 'actual' code. I have pasted the code below. It creates a Event Hub inside a Namespace. The code works perfectly executing in local machine but it does not execute in Runbook.
I have written a 'write-output "Declaring local variables for use in script"' --> to check if the printing is working. However, the code is not going beyond that. I am sure, I am missing some thing. Kindly help me.
Param(
[Parameter(Mandatory=$true)]
[string] $NameSpaceNameName,
[Parameter(Mandatory=$true)]
[string[]] $EventhubNames,
[Parameter(Mandatory=$true)]
[string] $ProjectId,
[Parameter(Mandatory=$true)]
[int] $PartitionCount,
[Parameter(Mandatory=$true)]
[string]$Requested_for,
[Parameter(Mandatory=$true)]
[string]$Comments
)
## Login to Azure using RunAsAccount
$servicePrincipalConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
Write-Output ("Logging in to Az Account...")
Login-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
write-output "Declaring local variables for use in script"
## Declaring local variables for use in script
$Creation_date = [System.Collections.ArrayList]#()
$ResourceGroups = Get-AzResourceGroup
$provided_name_space_exists = $false
## Change context to Platform subscription
select-azsubscription -subscription "GC302_Sub-platform_Dev"
## Create Event Hub
foreach($Resourcegroup in $ResourceGroups){
Write-Host("Processing the Resource Group: {0} " -f $Resourcegroup.ResourceGroupName)
$EventhubNameSpaces = Get-AzEventHubNamespace -ResourceGroupName $ResourceGroup.ResourceGroupName
# Iterate over each Namespace. Fetch the Resource Group that contains the provided Namespace
foreach($EHNameSpace in $EventhubNameSpaces){
if($EHNameSpace.Name -eq $NameSpaceName){
$provided_name_space_exists = $true
Write-Host ("Found the provided Namespace in resource group: {0}" -f $Resourcegroup.ResourceGroupName)
Write-Output ("Found the provided Namespace in resource group: {0}" -f $Resourcegroup.ResourceGroupName)
$nameSpace_resource_group = $ResourceGroup.ResourceGroupName
# Fetch the existing Event Hubs in the Namespace
$existing_event_hubs_list = Get-AzEventHub -Namespace $EHNameSpace.Name -ResourceGroupName $nameSpace_resource_group
## Check provided EH for uniqueness
if($existing_event_hubs_list.Count -le 1000){
for($i = 0;$i -lt $EventhubNames.Count;$i++){
if($existing_event_hubs_list.name -notcontains $EventhubNames[$i]){
$EventHub = New-AzEventHub -ResourceGroupName $nameSpace_resource_group -Namespace $EHNameSpace.Name -Name $EventhubNames[$i] -PartitionCount $PartitionCount
$date = $EventHub.CreatedAt
$Creation_date+= $date.GetDateTimeFormats()[46]
}else{
Write-Host ("Event hub: '{0}' already exists in the NameSpace: {1}. skipping this Event hub creation" -f $EventhubNames[$i], $EHNameSpace.Name)
}
}
}else{
Write-Host ("The Namespace - {0} has Event Hubs count greater or equal to 1000." -f $EHNameSpace.Name)
Write-Host ("Please refer the Link for Eevent Hubs quota/limit: 'https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-quotas#event-hubs-dedicated---quotas-and-limits'")
exit
}
}
}
}
# Print a message that Namespace does not exist
if($provided_name_space_exists -eq $false){
Write-Host ("Provided NameSpace: {0} does not exist." -f $NameSpaceName)
exit
}
Screenshot:
You have $NameSpaceNameName in the parameters section of the runbook but later in the runbook at 50th line you have $NameSpaceName which is not the same as mentioned in parameters section. Correct it and then it should work as expected. One suggestion is to always have an else block wherever you have if block to overcome such issues in future.

Get All blob names from Storage account from Runbook

I have a very simple script which absolutely works fine when run from remote powershell ISE (not using the RUNAS credentials from the Automation Runbook), but when we try to run it from Automation Runbook it returns 0 . Following is the code:-
$connectionName = "AzureRunAsConnection"
$SubId = "XXXXXXXXXXXXXXXXXX"
try
{
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
Write-Verbose "Logging in to Azure..." -Verbose
Connect-AzAccount -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint -ApplicationId $servicePrincipalConnection.ApplicationId -Tenant $servicePrincipalConnection.TenantId -ServicePrincipal
Write-Verbose "Setting Subscription......" -Verbose
Set-AzContext -SubscriptionId $SubId | Write-Verbose
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccountName -ErrorAction SilentlyContinue
# Resource group name for the storage acccount
$ResourceGroup = "MYDEV01-RG"
# Storage account name
$StorageAccountName = "myDev01StrgName"
# Container name for analytics logs
$ContainerName = "`$logs"
$storageContext = $storageAccount.Context
$containers = New-Object System.Collections.ArrayList
$container = Get-AzStorageContainer -Context $storageContext -Name $ContainerName -ErrorAction SilentlyContinue |
ForEach-Object { $containers.Add($_) } | Out-Null
Write-Output("> Container count: {0}" -f $containers.Count)
Not sure if we are missing something like permissions or some other thing because of with the Automation Account (Runbook) is not working, any help?
Thank you,
After spending 24 hours on this one and staring and trying everything, it turned out that the ABOVE SCRIPT is correct and nothing is wrong in it but the STORAGE ACCOUNT's FIREWALL and NETWORK Setting were set to SELECTED NETWORK (You can either add the network IP addresses which you want to permit or select All Networks and that helped me resolve my issue). In NO WAYS I am suggesting SELECTING ALL NETWORKS but for testing we can and then add only the Selected networks and that should work.

Create point-to-site connection for all web apps slots using powershell

I'm following the tutorial from here https://azure.microsoft.com/pl-pl/documentation/articles/app-service-vnet-integration-powershell/
where I've a script which allows me to connect multiple web apps with VNet.
The issue is our web apps have few deployment slots and when this script is run it only updates currently used slot.
I wasn't able to get web app from different slot by the name, also I don't see any parameter which would apply my configuration to all slots.
Script for the reference:
function ConnectWebAppWithVNet()
{
param(
$SubscriptionId,
$VNetResourceGroupName,
$AppResourceGroupName,
$WebAppName,
$VNetName,
$GatewayName,
$P2SRootCertName2,
$MyP2SCertPubKeyBase64_2
)
$webApp = Get-AzureRmResource -ResourceName $WebAppName -ResourceType "Microsoft.Web/sites" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName
$location = $webApp.Location
$vnet = Get-AzureRmVirtualNetwork -name $VNetName -ResourceGroupName $VNetResourceGroupName
$gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $vnet.ResourceGroupName -Name $GatewayName
# validate gateway types, etc.
if($gateway.GatewayType -ne "Vpn")
{
Write-Error "This gateway is not of the Vpn type. It cannot be joined to an App."
return
}
if($gateway.VpnType -ne "RouteBased")
{
Write-Error "This gateways Vpn type is not RouteBased. It cannot be joined to an App."
return
}
if($gateway.VpnClientConfiguration -eq $null -or $gateway.VpnClientConfiguration.VpnClientAddressPool -eq $null)
{
Write-Host "This gateway does not have a Point-to-site Address Range. Please specify one in CIDR notation, e.g. 10.0.0.0/8"
return
}
Write-Host "Creating App association to VNET"
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnetName)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $propertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName -Force
# We need to check if the certificate here exists in the gateway.
$certificates = $gateway.VpnClientConfiguration.VpnClientRootCertificates
$certFound = $false
foreach($certificate in $certificates)
{
if($certificate.PublicCertData -eq $virtualNetwork.Properties.CertBlob)
{
$certFound = $true
break
}
}
if(-not $certFound)
{
Write-Host "Adding certificate"
Add-AzureRmVpnClientRootCertificate -ResourceGroupName $VNetResourceGroupName -VpnClientRootCertificateName "AppServiceCertificate.cer" -PublicCertData $virtualNetwork.Properties.CertBlob -VirtualNetworkGatewayName $gateway.Name
}
# Now finish joining by getting the VPN package and giving it to the App
Write-Host "Retrieving VPN Package and supplying to App"
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
# Put the VPN client configuration package onto the App
$PropertiesObject = #{
"vnetName" = $vnet.Name; "vpnPackageUri" = $packageUri
}
New-AzureRmResource -Location $location -Properties $propertiesObject -ResourceName "$($webAppName)/$($vnet.Name)/primary" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName -Force
Write-Host "Finished!"
}
If your web app is already connected to VPN there is a way to connect also its slot.
$webAppName = "name_of_app_service"
$resourceGroup = "name_of_resource_group"
$vnetName = "name_of_vnet"
$slotName = "staging"
$resName = $webAppName + "/" + $slotName
$WebAppConfig = Get-AzureRmResource -ResourceGroupName $resourceGroup -ResourceType Microsoft.Web/sites/slots/config -ResourceName $resName -ApiVersion 2016-08-01
$WebAppConfig.Properties.vnetName = $vnetName
Set-AzureRmResource -ResourceId $WebAppConfig.ResourceId -Properties $WebAppConfig.Properties -ApiVersion 2016-08-01 # -Force
I've manged to get help from Azure support and we've found out the problem:
I've created secondary slot without cloning the configuration
settings from main slot. If this setting would be selected,
secondary slot would be connected automatically. In my case I couldn't recreate slot so I needed to manually
connect secondary slot after swapping.

Azure database backup to blob using Powershell

We need to backup the azure database and store it on blob so that it can be restored. I've seen this blog but it uses the third party cmdlets.
http://weblogs.thinktecture.com/cweyer/2011/01/automating-backup-of-a-sql-azure-database-to-azure-blob-storage-with-the-help-of-powershell-and-task-scheduler.html
Could someone please guide/help how above can be achieved using powershell.
Backing up to WA Blob Store is not supported from Azure DB, rather the service does automatic backups for you with PITR capability. You'll find the following documentation useful:
http://msdn.microsoft.com/en-us/library/azure/hh852669.aspx
http://msdn.microsoft.com/en-us/library/azure/jj650016.aspx
Hope this helps.
Here is my powershell script
https://gist.github.com/voxon2/be29a3fd6dabbb9155ca
Here is an article describing many different approaches other than powershell
http://blogs.msdn.com/b/mast/archive/2013/03/04/different-ways-to-backup-your-windows-azure-sql-database.aspx
First get your Azure Automation Settings done (see here).
Edit the blow script and save it as .ps1 file. When you run it for
the first time, it will ask you both your azure automation account and
your database credentials. During this process, it will save your
credentials in a local file securely (see here how it is done). After this time on wards, it uses the saved credentials.
The .psl file and the encrypted credential files should be stored in one
directory
Once you are happy you can schedule it to run in task scheduler.
function Get-MyCredential
{
param(
$CredPath,
[switch]$Help
)
$HelpText = #"
Get-MyCredential
Usage:
Get-MyCredential -CredPath `$CredPath
If a credential is stored in $CredPath, it will be used.
If no credential is found, Export-Credential will start and offer to
Store a credential at the location specified.
"#
if($Help -or (!($CredPath))){write-host $Helptext; Break}
if (!(Test-Path -Path $CredPath -PathType Leaf)) {
Export-Credential (Get-Credential) $CredPath
}
$cred = Import-Clixml $CredPath
$cred.Password = $cred.Password | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PsCredential($cred.UserName, $cred.Password)
Return $Credential
}
function Export-Credential($cred, $path) {
$cred = $cred | Select-Object *
$cred.password = $cred.Password | ConvertFrom-SecureString
$cred | Export-Clixml $path
}
#Create a directory with you azure server name to isolate configurations
$FileRootPath = "C:\PowerShellScripts\AzureServerName"
Write-Host "Getting Azure credentials"
$AzureCred = Get-MyCredential ($FileRootPath + "AzureSyncred.txt")
#Use Azure Automation Account
#(If You do not have it will not work with other accounts)
Add-AzureAccount -Credential $AzureCred
Select-AzureSubscription -SubscriptionId "myAzureSubscriptionId"
#DO NOT use tcp:myServerName.database.windows.net,1433 but only myServerName
$ServerName = "myServerName"
$Date = Get-Date -format "yyyy-MM-dd-HH-mm"
$DatabaseName = "myTargetDatabaseName"
$BlobName = $Date + "-" + $DatabaseName.bacpac"
$StorageName = "myStorageAccountName"
$ContainerName = "myContainerNameToStoreBacpacFiles"
$StorageKey = "myStorageAccountKey"
Write-Host "Getting database user credential"
#DO NOT use myDatabaseUsername#myServerName but only myDatabaseUsername
$credential = Get-MyCredential ($FileRootPath + "DbSyncred.xml")
Write-Host "Connecting to Azure database"
$SqlCtx = New-AzureSqlDatabaseServerContext -ServerName $ServerName -Credential $credential
Write-Host "Connecting to Blob storage"
$StorageCtx = New-AzureStorageContext -StorageAccountName $StorageName -StorageAccountKey $StorageKey
$Container = Get-AzureStorageContainer -Name $ContainerName -Context $StorageCtx
Write-Host "Exporting data to blob"
$exportRequest = Start-AzureSqlDatabaseExport -SqlConnectionContext $SqlCtx -StorageContainer $Container -DatabaseName $DatabaseName -BlobName $BlobName
Get-AzureSqlDatabaseImportExportStatus -Request $exportRequest
# use the below script in powershell to execute the script
# powershell -ExecutionPolicy ByPass –File C:\PowerShellScripts\AzureServerName\mySavedScript.ps1 –noexit