Azure with PowerShell: empty string for Identity - azure

I have a PowerShell script that logs into Azure and assign a group call membership to a user based on the input email address the user gave:
Function SetUser
{
$script:user = Read-Host -Prompt "Enter the user's email address"
Write-Host "You set the email address as '$user'." -ForegroundColor yellow
}
Function Assigndelegate($user)
{
$job = Start-Job -ScriptBlock {
param($user)
New-CsUserCallingDelegate -Identity $identity -Delegate $user -MakeCalls $true -ReceiveCalls $true -ManageSettings $false
} -ArgumentList $user
while ($job.State -eq 'Running') {
Write-Host "Connecting to Azure..."
Wait-Job -Job $job
}
$result = Receive-Job $job
(Get-CsUserCallingSettings -Identity $user).Delegators | ft -Property Id, MakeCalls, ReceiveCalls, ManageSettings
}
Connect-MicrosoftTeams
$script:identity = "user#contoso.com"
SetUser
Assigndelegate $user
This gives me the following error:
Cannot bind argument to parameter 'Identity' because it is an empty string.
+ CategoryInfo : InvalidData: (:) [New-CsUserCallingDelegate], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,New-CsUserCallingDelegate
+ PSComputerName : localhost
What I understand is that it cannot read the variable $identity, but I don't see the reason why: I tried also with the "$global:" prefix to see it works, even though that would not be ideal as this changes later, got the same error. If I directly add the value of this variable, it works.
If I define Identity in the same name in the 'param' and 'ArgumentList' the error changes to:
Cannot bind argument to parameter 'Identity' because it is an empty string.
+ CategoryInfo : InvalidData: (:) [New-CsUserCallingDelegate], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,New-CsUserCallingDelegate
+ PSComputerName : localhost
Get-CsUserCallingSettings : Cannot process argument transformation on parameter 'Identity'. Cannot convert value to type System.String.
At line:36 char:42
+ (Get-CsUserCallingSettings -Identity $user).Delegators | ft -Prop ...
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Get-CsUserCallingSettings], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-CsUserCallingSettings
UPDATE:
After Updating the argument list, I still get the error:
#Set the user
Function SetUser
{
$script:user = Read-Host -Prompt "Enter the user's email address"
Write-Host "You set the email address as '$user'." -ForegroundColor yellow
}
Function Assigndelegate($user, $identity)
{
$job = Start-Job -ScriptBlock {
param($user, $identity)
New-CsUserCallingDelegate -Identity $identity -Delegate $user -MakeCalls $true -ReceiveCalls $true -ManageSettings $false
} -ArgumentList #($user, $identity)
while ($job.State -eq 'Running') {
Write-Host "Connecting to Azure..."
Wait-Job -Job $job
}
$result = Receive-Job $job
#(Get-CsUserCallingSettings -Identity $user).Delegators | ft -Property Id, MakeCalls, ReceiveCalls, ManageSettings
}
Connect-MicrosoftTeams
$script:identity = "user#contoso.com"
SetUser
Assigndelegate $user, $identity
UPDATE II
Based on the idea recommended I simplified the script:
Function SetUser
{
$script:user = Read-Host -Prompt "Enter the user's email address"
Write-Host "You set the email address as '$user'." -ForegroundColor yellow
}
Function Assigndelegate($user, $identity)
{
Write-Output $identity
}
$script:identity = "user#contoso.com"
SetUser
Assigndelegate $user, $identity
It gives no results apart from:
"You set the email address as '$user'." -ForegroundColor yellow

The Start-Job cmdlet starts a process in a separate session, so none of the scopes (local, script or global) are visible to the script block it executes. The only way around this is to add identity as a parameter in your script block and pass it explicitly, i.e:
Function SetUser
{
$script:user = Read-Host -Prompt "Enter the user's email address"
Write-Host "You set the email address as '$user'." -ForegroundColor yellow
}
Function Assigndelegate($user, $identity)
{
$job = Start-Job -ScriptBlock {
param($user, $identity)
New-CsUserCallingDelegate -Identity $identity -Delegate $user -MakeCalls $true -ReceiveCalls $true -ManageSettings $false
} -ArgumentList #($user, $identity)
while ($job.State -eq 'Running') {
Write-Host "Connecting to Azure..."
Wait-Job -Job $job
}
$result = Receive-Job $job
(Get-CsUserCallingSettings -Identity $user).Delegators | ft -Property Id, MakeCalls, ReceiveCalls, ManageSettings
}
Connect-MicrosoftTeams
$script:identity = "user#contoso.com"
SetUser
Assigndelegate -user $user -identity $identity

Related

I need to Run this PowerShell script in different servers remotely with credentials & collect data in single csv and send to email

I need to Run this PowerShell script in different servers remotely with credentials & collect data in single csv and send to email. i Include the Invoke Command, but getting error.
$servers = Get-Content "c:\serverlist\servers.txt"
$Report = foreach ($server in $servers){
Invoke-Command -ComputerName $server -ScriptBlock
}
{
$props = #(
#{
N='ServerName'
E={ $env:COMPUTERNAME }
}
'StartDate'
'EndDate'
'ConnectorName'
'RunProfileName'
'StepResult'
)
$profiles = #(
'Delta Import'
'Delta Synchronization'
'Full Import'
'Full Synchronization'
) -join '|'
Get-ADSyncToolsRunstepHistory | Group-Object RunProfileName |
Where-Object Name -Match $profiles | ForEach-Object {
$_.Group | Select-Object -First 2
} } | Select-Object $props | Export-Csv c:\serverlist\export.csv -NoTypeInformation
I followed the steps to Send the date of the csv file to the email
In PowerShell ISE I have created a file and replaced the code below
the other method is a powerShell
$CSVFile ="C:\Users\Public\Downloads\users.csv"
$userList = import-csv $CSVFile
$subject = " Here is your Details"
$from ="yourmail"
$passwrod ="your password"|convertTo-secureString -asPlainText -force
$creds = new-object -TypeName System.Management.Automation.PSCredential -ArgumentList $from ,$passwrod
foreach ($user in $userList){
$body = "your Login Id is" +$user.loginname
$body += "your password is" + $user.Passwrod
$body +="your email id is " + $user.mail
Send-MailMessage -From $from $user.mail -Subject $subject -body $body - SmtpServer "pujarisampath80#gmail.com" -UseSs1 -port 587 -Credential $creds
}
I have created csv file In Excel
With .csv extension
Provide your Email address and password and click on Run and check the mail

How to use a variable ForegroundColor with write-host onto Start-job

I'm stuck into a little problem that I don't understand, here is a simplified version of my code :
[hashtable] $result_color = #{
OPENED = [ConsoleColor]::green;
FERME = [ConsoleColor]::red
}
$job = Start-Job -Name "test" -Scriptblock {
Write-Host "Test text" -ForegroundColor $result_color.OPENED
} -ArgumentList $result_color
Wait-Job $job | Out-Null
Receive-Job $job
I get the following error :
Unable to bind "ForegroundColor" parameter to target. Exception when defining "ForegroundColor": "Unable to convert Null value to "System.ConsoleColor" type due to invalid enumeration values."
I also tried this :
[hashtable] $result_color= #{
OPENED = [System.ConsoleColor] "green";
CLOSED = [System.ConsoleColor] "red"
}
$job = Start-Job -Name "test" -Scriptblock {
Write-Host "Test text" -ForegroundColor $result_color.OPENED
} -ArgumentList $result_color
Wait-Job $job | Out-Null
Receive-Job $job
But same error... Thanks in advance for your help !
Either do what Mathias commented, OR add a param block into your scriptblock and use the -ArgumentList parameter to feed it the correct value like
$job = Start-Job -Name "test" -Scriptblock {
param($color)
Write-Host "Test text" -ForegroundColor $color
} -ArgumentList $result_color.OPENED

How to add resource group as one factor to filter the output

<#
NAME
AzureSubscriptionRBACAudit.ps1
SYNOPSIS
Gathers Azure Role Based Access Control Data for Audit Purposes.
DESCRIPTION
Gathers Azure Role Based Access Control Data for Audit Purposes. The script will prompt the user to
select a subscription to run the audit against. The user is only presented the scriptions currently
available to the users credentials.
OUTPUTS
Outputs a CSV file in the same directory that the script is located in. The CSV file will have the
name of the subscription in its title followed by "Azure RBAC Audit.csv"
#>
Functions
Function Login {
<#
.SYNOPSIS
Runs the Azure Login Command
#>
$needLogin = $true
Try {
$content = Get-AzContext
if ($content) {
$needLogin = ([string]::IsNullOrEmpty($content.Account))
}
}
Catch {
if ($_ -like "*Login-AzAccount to login*") {
$needLogin = $true
}
else {
throw
}
}
if ($needLogin) {
#Login-AzAccount
Select-Azure
}
}
Function Select-Azure{
<#
.SYNOPSIS
Provides a list of Azure Environments for the user to select from.
AzureGov, AzureCloud, etc.
#>
Clear-Host
$ErrorActionPreference = 'SilentlyContinue'
$Menu = 0
$AzEnvironment = #(Get-AzEnvironment |select-object Name)
Write-Host "Please select the Azure Environment you want to use:" -ForegroundColor Green;
ForEach-Object {Write-Host ""}
$AzEnvironment | ForEach-Object {Write-Host "[$($Menu)]" -ForegroundColor Cyan -NoNewline ; Write-host ". $($_.Name)"; $Menu++; }
ForEach-Object {Write-Host ""}
ForEach-Object {Write-Host "[Q]" -ForegroundColor Red -NoNewline ; Write-host ". To quit."}
ForEach-Object {Write-Host ""}
$selection = Read-Host "Please select the Azure Environment Number - Valid numbers are 0 - $($AzEnvironment.count -1) or Q to quit"
If ($selection -eq 'Q') {
Clear-Host
Exit
}
If ($AzEnvironment.item($selection) -ne $null)
{ Connect-AzAccount -EnvironmentName $AzEnvironment.item($selection).Name -ErrorAction Stop}
}
Function Select-Subs {
<#
.SYNOPSIS
Provides a list of subscriptions for the user to select from.
#>
Clear-Host
$ErrorActionPreference = 'SilentlyContinue'
$Menu = 0
$Subs = #(Get-AzSubscription | Select-Object Name, ID, TenantId)
Write-Host "Please select the subscription you want to use:" -ForegroundColor Green;
ForEach-Object {Write-Host ""}
$Subs | ForEach-Object {Write-Host "[$($Menu)]" -ForegroundColor Cyan -NoNewline ; Write-host ". $($_.Name)"; $Menu++; }
ForEach-Object {Write-Host ""}
ForEach-Object {Write-Host "[S]" -ForegroundColor Yellow -NoNewline ; Write-host ". To switch Azure Account."}
ForEach-Object {Write-Host ""}
ForEach-Object {Write-Host "[Q]" -ForegroundColor Red -NoNewline ; Write-host ". To quit."}
ForEach-Object {Write-Host ""}
$selection = Read-Host "Please select the Subscription Number - Valid numbers are 0 - $($Subs.count -1), S to switch Azure Account or Q to quit"
If ($selection -eq 'S') {
Get-AzContext | ForEach-Object {Clear-AzContext -Scope CurrentUser -Force}
Select-Azure
Select-Subs
}
If ($selection -eq 'Q') {
Clear-Host
Exit
}
If ($Subs.item($selection) -ne $null)
{ Return #{name = $subs[$selection].Name; ID = $subs[$selection].ID}
}
}
Function Resolve-AzAdGroupMembers {
<#
.SYNOPSIS
Gets list of Azure Active Directory groups and its members
#>
param(
[guid]
$GroupObjectId,
$GroupList
)
$VerbosePreference = 'continue'
Write-Verbose -Message ('Resolving {0}' -f $GroupObjectId)
$group = $GroupList | Where-Object -Property Id -EQ -Value $GroupObjectId
$groupMembers = Get-AzADGroupMember -GroupObjectId $GroupObjectId
Write-Verbose -Message ('Found members {0}' -f ($groupMembers.DisplayName -join ', '))
$parentGroup = #{
Id = $group.Id
DisplayName = $group.DisplayName
}
$groupMembers |
Where-Object -Property Type -NE -Value Group |
Select-Object -Property Id, DisplayName, #{
Name = 'ParentGroup'
Expression = { $parentGroup }
}
$groupMembers |
Where-Object -Property type -EQ -Value Group |
ForEach-Object -Process {
Resolve-AzAdGroupMembers -GroupObjectId $_.Id -GroupList $GroupList
}
}
Main Part of Script
Write-Output "Running login script"
Login # Login to Azure
$SubscriptionSelection = Select-Subs # Runs function to get Azure subscriptions available to user and sets the subscription to the users choice.
Select-AzSubscription -SubscriptionName $SubscriptionSelection.Name -ErrorAction Stop
## Get current Azure Subscription Name to be used in reporting output
$Azuresub = $SubscriptionSelection.Name -replace , '/'
ForEach-Object {Write-Host "Getting Azure AD Groups" -ForegroundColor Yellow -NoNewline}
ForEach-Object {Write-Host "`r`n========================================" -ForegroundColor Yellow -NoNewline}
ForEach-Object {Write-Host "`nThis process can take a while to run since it is checking every Azure Role and its corresponding assignments." -ForegroundColor Yellow -NoNewline }
$GroupList = (Get-AzADGroup)
ForEach-Object {Write-Host "Getting Role Assignments" -ForegroundColor Yellow -NoNewline}
ForEach-Object {Write-Host "`r`n========================================" -ForegroundColor Yellow -NoNewline}
$roleAssignments = Get-AzRoleAssignment -IncludeClassicAdministrators
## Loop through each role assignment to determine the user assigned to that role.
$members = $roleAssignments | ForEach-Object -Process {
Write-Verbose -Message ('Processing Assignment {0}' -f $_.RoleDefinitionName)
$roleAssignment = $_
if($roleAssignment.ObjectType -eq 'Group')
{
Resolve-AzAdGroupMembers -GroupObjectId $roleAssignment.ObjectId -GroupList $GroupList `
| Select-Object -Property Id,
DisplayName,
ParentGroup, #{
Name = 'RoleDefinitionName'
Expression = { $roleAssignment.RoleDefinitionName }
}, #{
Name = 'Scope'
Expression = { $roleAssignment.Scope }
}, #{
Name = 'CanDelegate'
Expression = { $roleAssignment.CanDelegate }
}
}
else
{
$roleAssignment | Select-Object -Property #{
Name = 'Id'
Expression = { $_.ObjectId }
},
DisplayName,
#{
Name = 'RoleDefinitionName'
Expression = { $roleAssignment.RoleDefinitionName }
},
Scope,
CanDelegate
}
}
Generating CSV Output for reporting
$outtbl = #()
$members | ForEach-Object {
$x = New-Object PSObject -Property #{
Subscription = $Azuresub -join ','
ActiveDirID = $_.Id -join ','
DisplayName = $_.DisplayName -join ','
ParentGroupID = $_.ParentGroup.Id -join ','
ParentGroupDisplayName = $_.ParentGroup.DisplayName -join ','
RoleDefinitionName = $_.RoleDefinitionName -join ','
Scope = $_.Scope
}
$outtbl += $x
}
$outtbl | Select-Object Subscription,ActiveDirID,DisplayName,ParentGroupID,ParentGroupDisplayName,RoleDefinitionName, Scope |Export-CSV -path $($PSScriptRoot + "\" + "$Azuresub" + " Azure RBAC Audit.csv") -NoTypeInformation
ForEach-Object {Write-Host " `r`nRBAC Audit has completed. Your CSV file is located: $($PSScriptRoot + "\" + "$Azuresub" + " Azure RBAC Audit.csv")" -ForegroundColor Green -NoNewline }
Above code is working fine for complete subscription but we need to filter the output only for resoucegroup. so how to add one more function to get output only based on reouce group.
https://github.com/arnoldna/RBACReporting/blob/master/AzureSubscriptionRBACAudit.ps1
For your requirement, just use the -ResourceGroupName parameter in the command Get-AzRoleAssignment to specify the resource group you want in Main Part of Script.
$roleAssignments = Get-AzRoleAssignment -IncludeClassicAdministrators -ResourceGroupName <ResourceGroupName>
Note: The RBAC role permissions are inherited, e.g. if a user/service principal/AAD group has an RBAC role at the subscription/management group scope, it will also have the permission at all the resource groups located in the subscription/management group, so the command above will also get the role assignments that assigned at the subscription/management group scope, the management group is a higher scope than subscription, refer to this link.
So if you just want to get the role assignment that directly assigned to the resource group/single resource in the resource group, modify the command as below, it depends on your reqirement.
$roleAssignments = Get-AzRoleAssignment -IncludeClassicAdministrators -ResourceGroupName <ResourceGroupName> | Where-Object {$_.Scope -like '/subscriptions/*/resourceGroups/*'}

Azure Runbook Commands

So I have a runbook which automates the shutdown and start-up of my Azure VM during the weekends. This then sends a transactional email confirming that the VPS is shut down/started up.
I have set up my parameters as illustrated. Is there a reason as to why it correctly states the name of my virtual machine (highlighted) in the subject line but in the body of the email (highlighted), it comes up with a completely different name.
Logic would dictate that $VM.NAME would be the name of the VPS and not some random command line, so why is this? It's displayed correctly in the subject line but not the email body.
param (
[Parameter(Mandatory=$false)]
[String] $VMName ="ITAMTRADINGVPS",
[Parameter(Mandatory=$false)]
[String] $ResourceGroupName
)
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
# If there is a specific resource group, then get all VMs in the resource group,
# otherwise get all VMs in the subscription.
if ($ResourceGroupName -And $VMName)
{
$VMs = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VMName
}
elseif ($ResourceGroupName)
{
$VMs = Get-AzureRmVM -ResourceGroupName $ResourceGroupName
}
else
{
$VMs = Get-AzureRmVM
}
$vms
# Start each of the VMs
# Stop each of the VMs
foreach ($VM in $VMs)
{
$StopRtn = $VM | Stop-AzureRmVM -Force -ErrorAction Continue
$StopRtn
Write-Output " this is $StopRtn "
if ($StopRtn.IsSuccessStatusCode -eq 'True')
{
# The VM stopped, so send notice
Write-Output ($VM.Name + " has been stopped")
$Username ="xxx"
$Password = ConvertTo-SecureString "xxx" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $Username, $Password
$SMTPServer = "xxx"
$EmailFrom = "xxxx
[string[]]$EmailTo = "xxx"
$Subject = $VM.NAME + " notification of scheduled deallocation"
$Body = "We'd like to let you know that your Virtual Machine $VM.NAME has successfully deallocated.
<br>This could either be due to maintenance or a scheduled shutdown. If you were expecting this notification, please disregard this email.
<br><br>If you need any further assistance, please contact the system administrator on xxx<br><br>Yours Sincerely<br><br>The Technical Design Team<br>xxx<br><br>"
Send-MailMessage -smtpServer $SMTPServer -Credential $credential -Usessl -Port 587 -from $EmailFrom -to $EmailTo -subject $Subject -Body $Body -BodyAsHtml
Write-Output "Email sent succesfully."
}
else
{
# The VM failed to stop, so send notice
Write-Output ($VM.Name + " failed to stop")
}
}
Illustration
The variable reference (e.g. $VM.Name) into the email body which by default will just return the object type where the output in PowerShell is a special pipeline activity which will render the content either as a listing or as a table. In order to include content in an email, we would have to reference the properties
[string]$EmailBody = (“VMNAME IS = [{0}]” -f $VM.Name)
which is similar to string.format in C#
Refer this SO

Cannot find type Microsoft.WindowsAzure.Commands.SqlDatabase.Services.ImportExportRequest

I am backing up Azure SQL Database with PowerShell. The final part of the script, which is working fine, is this:
Write-Output "Exporting databases"
foreach ($db in $azSqlServerDatabases) {
$exportRequest = Start-AzureSqlDatabaseExport -SqlConnectionContext $azSqlStageConnContext -StorageContainer $container -DatabaseName $db.Name -BlobName ($db.Name + ".bacpac")
$exportRequests.Add($exportRequest)
Write-Output ($db.Name + ".bacpac")
}
I am trying to create generic list:
$exportRequests = New-Object 'System.Collections.Generic.List[Microsoft.WindowsAzure.Commands.SqlDatabase.Services.ImportExportRequest]'
Which must hold the results of the requests. The problem is that when I create the generic list I get an error:
New-Object : Cannot find type [System.Collections.Generic.List[Microsoft.WindowsAzure.Commands.SqlDatabase.Services.ImportExportRequest]]: verify that the assembly containing this type is lo
aded.
At C:...
+ ... tRequests = New-Object 'System.Collections.Generic.List[Microsoft.Win ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
Where can I find this type? Why it is not included - I am calling Start-AzureSqlDatabaseExport successfully and I get the result object - so the type is known already.
Trying to create just one object of the type manually in the Azure PowerShell Console throws the same exception:
PS C:\> $x = new-object 'Microsoft.WindowsAzure.Commands.SqlDatabase.Services.ImportExportRequest'
new-object : Cannot find type [Microsoft.WindowsAzure.Commands.SqlDatabase.Services.ImportExportRequest]: verify that t
he assembly containing this type is loaded.
At line:1 char:6
+ $x = new-object 'Microsoft.WindowsAzure.Commands.SqlDatabase.Services ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
PS C:\>
I got the output type from MS documentation.
I ran getType() on the object returned by Start-AzureSQLDatabaseExport. Looks like you ran into a type issue. The actual type of the object returned by Start-AzureSQLDatabaseExport is Microsoft.WindowsAzure.Commands.SqlDatabase.Model.SqlDatabaseServerOperationContext.
Try declaring your list like below:
$exportRequests = New-Object 'System.Collections.Generic.List[Microsoft.WindowsAzure.Commands.SqlDatabase.Model.SqlDatabaseServerOperationContext]'
Thank you #elfisher for the assistance. Here is the final version of my command just in case somebody find it helpful. It helps me export all the dbs from azure server during dev and test.
# The command will prompt only once for most parameters during one session
param(
[string] $azSubscriptionId,
[string] $azStorageName,
[string] $azStorageKey,
[string] $azContainerName,
[string] $azSqlServerName,
[string] $azSqlServerUserName,
[string] $azSqlServerPassword)
#if you want to clean up all globally created vars => Remove-Variable -Name 'az*'
Remove-Variable -Name 'az*'
#Remove-Variable -Name 'azAccount' # clean up acc credentials. Can be removed but once in a while the credentials for the account get expired
#region azAccount
$azAccount = Get-AzureAccount
if(!$azAccount)
{
Do
{
Write-Output "No azure account. Prompting ..."
$azAccount = Add-AzureAccount
} While (!$azAccount)
Set-Variable -Name azAccount -Value $azAccount -Scope Global
$azAccount = Get-AzureAccount
}
#endregion
#region azSubscriptionId
if(!$azSubscriptionId)
{
Do
{
Write-Output "No subscription Id. Prompting ..."
$azSubscriptionId = Read-Host "Subscription Id"
} While (!$azSubscriptionId)
Write-Output "Input for subscription Id $azSubscriptionId"
Set-Variable -Name azSubscriptionId -Value $azSubscriptionId -Scope Global
}
Select-AzureSubscription -SubscriptionId $azSubscriptionId
Write-Output "Selected subscription Id $azSubscriptionId"
#endregion
#region azStorageName
if(!$azStorageName)
{
Do
{
Write-Output "No storage name. Prompting ..."
$azStorageName = Read-Host "storage name"
} While (!$azStorageName)
Set-Variable -Name storageName -Value $azStorageName -Scope Global
}
#endregion
#region azStorageKey
if(!$azStorageKey)
{
Do
{
Write-Output "No storage key. Prompting ..."
$azStorageKey = Read-Host "storage key"
} While (!$azStorageKey)
Set-Variable -Name azStorageKey -Value $azStorageKey -Scope Global
}
#endregion
#region azContainerName
if(!$azContainerName)
{
Do
{
Write-Output "No container name. Prompting ..."
$azContainerName = Read-Host "container name"
} While (!$azContainerName)
Set-Variable -Name azContainerName -Value $azContainerName -Scope Global
}
#endregion
#region azSqlServerName
if(!$azSqlServerName)
{
Do
{
Write-Output "No sql server name. Prompting ..."
$azSqlServerName = Read-Host "sql server name"
} While (!$azSqlServerName)
Set-Variable -Name azSqlServerName -Value $azSqlServerName -Scope Global
}
#endregion
#region azSqlServer
if(!$azSqlServer)
{
Write-Output "No sql server variable stored on this PC. Prompting ..."
$azSqlServer = Get-AzureSqlDatabaseServer -ServerName $azSqlServerName
Set-Variable -Name azSqlServer -Value $azSqlServer -Scope Global
}
#endregion
#region azSqlServerCredenials
if(!$azSqlServerCredenials)
{
Do
{
Write-Output "No sql server credentials. Prompting ..."
$azSqlServerCredenials = Get-Credential "Enter Credentials for $azSqlServerName"
} While (!$azSqlServerCredenials)
Set-Variable -Name azSqlServerCredenials -Value $azSqlServerCredenials -Scope Global
}
#endregion
#region Sql connection context
if(!$azSqlCtx)
{
Write-Output "No Sql Server Context. Creating..."
$azSqlCtx = New-AzureSqlDatabaseServerContext -ServerName $azSqlServer.ServerName -Credential $azSqlServerCredenials
Set-Variable -Name azSqlCtx -Value $azSqlCtx -Scope Global
Write-Output "Sql Server Context for $azSqlServer.ServerName created."
}
#endregion
#region Storage connection context
if(!$azStorageCtx)
{
Write-Output "No Storage Context. Creating..."
$azStorageCtx = New-AzureStorageContext -StorageAccountName $azStorageName -StorageAccountKey $azStorageKey
Set-Variable -Name azStorageCtx -Value $azStorageCtx -Scope Global
Write-Output "Storage context for $azStorageName created."
}
#endregion
#region Storage container ref
if(!$azStorageContainer)
{
Write-Output "No container ref. Creating for $azContainerName"
$azStorageContainer = Get-AzureStorageContainer -Name $azContainerName -Context $azStorageCtx
Set-Variable -Name azStorageContainer -Value $azStorageContainer -Scope Global
Write-Output "Container ref to $azStorageContainer created."
}
#endregion
#region Sql Databases ref
if(!$azSqlServerDatabases)
{
Write-Output "No Sql Databases array ref. Creating..."
$azSqlServerDatabases = Get-AzureSqlDatabase -ConnectionContext $azSqlCtx
Set-Variable -Name azSqlServerDatabases -Value $azSqlServerDatabases -Scope Global
Write-Output "Sql Databases array ref created."
}
#endregion
#region actual export of azure databases
$exportRequests = New-Object 'System.Collections.Generic.List[Microsoft.WindowsAzure.Commands.SqlDatabase.Model.SqlDatabaseServerOperationContext]'
Write-Output "Exporting databases"
foreach ($db in $azSqlServerDatabases) {
$exportRequest = Start-AzureSqlDatabaseExport -SqlConnectionContext $azSqlCtx -StorageContainer $azStorageContainer -DatabaseName $db.Name -BlobName ($db.Name + ".bacpac")
$exportRequests.Add($exportRequest)
Write-Output ($db.Name + ".bacpac")
}
#endregion
#import dbs back into your local server
#cd [FOLDERPATH]
#$goodlist = dir
# probably the correct path
##C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\120
#cd 'C:\Program Files (x86)\Microsoft SQL Server\110\DAC\bin'
#foreach($i in $goodlist){ $name = $i.Name; $namer = $i.Name.Substring(0, $i.Name.length - 7); .\SqlPackage.exe /a:Import /sf:[FOLDERPATH]\$name /tdn:$namer /tsn:[SERVERNAME] }

Resources