├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── azure-portal └── portal-dashboard-template-testvm.json ├── azure-sql ├── database │ └── failover-groups │ │ ├── add-elastic-pool-to-failover-group-az-ps.ps1 │ │ └── add-single-db-to-failover-group-az-ps.ps1 ├── managed-instance │ ├── create-and-configure-managed-instance.ps1 │ └── failover-groups │ │ └── add-managed-instance-to-failover-group-az-ps.ps1 └── virtual-machine │ └── create-sql-server-vm.ps1 ├── container-registry ├── README.md ├── service-principal-assign-role │ └── service-principal-assign-role.ps1 └── service-principal-create │ └── service-principal-create.ps1 ├── expressroute-gateway └── gateway-migration │ ├── README.md │ ├── commitmigration.ps1 │ ├── migration.ps1 │ └── preparemigration.ps1 ├── expressroute └── highAvailabilitySetup │ ├── Get-AzExpressRouteResilientLocations.md │ ├── Get-AzExpressRouteResilientLocations.ps1 │ ├── New-AzHighAvailabilityExpressRouteCircuits.md │ ├── New-AzHighAvailabilityExpressRouteCircuits.ps1 │ ├── New-AzHighAvailabilityVirtualNetworkGatewayConnections.md │ └── New-AzHighAvailabilityVirtualNetworkGatewayConnections.ps1 ├── hdinsight └── create-cluster │ └── create-cluster.ps1 ├── managed-disks └── create-managed-disks-from-vhd-in-different-subscription.ps1 ├── storage └── calculate-container-size │ └── calculate-container-sizes-in-account.ps1 └── virtual-network-manager └── automate-vnet-ip-address-management.ps1 /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | > Please provide us with the following information: 5 | > --------------------------------------------------------------- 6 | 7 | ### This issue is for a: (mark with an `x`) 8 | ``` 9 | - [ ] bug report -> please search issues before submitting 10 | - [ ] feature request 11 | - [ ] documentation issue or request 12 | - [ ] regression (a behavior that used to work and stopped in a new release) 13 | ``` 14 | 15 | ### Minimal steps to reproduce 16 | > 17 | 18 | ### Any log messages given by the failure 19 | > 20 | 21 | ### Expected/desired behavior 22 | > 23 | 24 | ### OS and Version? 25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) 26 | 27 | ### Versions 28 | > 29 | 30 | ### Mention any other details that might be useful 31 | 32 | > --------------------------------------------------------------- 33 | > Thanks! We'll be in touch soon. 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # PR Summary 2 | 3 | 11 | 12 | ## PR Checklist 13 | 14 | 20 | 21 | - [ ] **Documentation use only:** This PR contains non-production samples used in Microsoft's official Azure PowerShell documentation. 22 | - [ ] **Azure PowerShell use only:** The samples in this PR contain commands from the Az PowerShell module. 23 | - [ ] **Sample scripts only:** This PR does not contain PowerShell modules, binaries, tools, images, zip or tar.gz files, or other files that are not samples. 24 | - [ ] **Validated samples:** I have validated these samples using the latest version of the Az PowerShell module. 25 | - [ ] **Ongoing support:** I agree to provide ongoing support for these samples and will promptly respond to issues and PRs. 26 | 27 | 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [project-title] Changelog 2 | 3 | 4 | # x.y.z (yyyy-mm-dd) 5 | 6 | *Features* 7 | * ... 8 | 9 | *Bug Fixes* 10 | * ... 11 | 12 | *Breaking Changes* 13 | * ... 14 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | - Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support) 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Azure Docs PowerShell Samples 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 6 | 7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 9 | provided by the bot. You will only need to do this once across all repos using our CLA. 10 | 11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 14 | 15 | - [Code of Conduct](#coc) 16 | - [Issues and Bugs](#issue) 17 | - [Feature Requests](#feature) 18 | - [Submission Guidelines](#submit) 19 | 20 | ## Code of Conduct 21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 22 | 23 | ## Found an Issue? 24 | If you find a bug in the source code or a mistake in the documentation, you can help us by 25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can 26 | [submit a Pull Request](#submit-pr) with a fix. 27 | 28 | ## Want a Feature? 29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub 30 | Repository. If you would like to *implement* a new feature, please submit an issue with 31 | a proposal for your work first, to be sure that we can use it. 32 | 33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). 34 | 35 | ## Submission Guidelines 36 | 37 | ### Submitting an Issue 38 | Before you submit an issue, search the archive, maybe your question was already answered. 39 | 40 | If your issue appears to be a bug, and hasn't been reported, open a new issue. 41 | Help us to maximize the effort we can spend fixing issues and adding new 42 | features, by not reporting duplicate issues. Providing the following information will increase the 43 | chances of your issue being dealt with quickly: 44 | 45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps 46 | * **Version** - what version is affected (e.g. 0.1.2) 47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you 48 | * **Browsers and Operating System** - is this a problem with all browsers? 49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps 50 | * **Related Issues** - has a similar issue been reported before? 51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be 52 | causing the problem (line of code or commit) 53 | 54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new]. 55 | 56 | ### Submitting a Pull Request (PR) 57 | Before you submit your Pull Request (PR) consider the following guidelines: 58 | 59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR 60 | that relates to your submission. You don't want to duplicate effort. 61 | 62 | * Make your changes in a new git fork: 63 | 64 | * Commit your changes using a descriptive commit message 65 | * Push your fork to GitHub: 66 | * In GitHub, create a pull request 67 | * If we suggest changes then: 68 | * Make the required updates. 69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request): 70 | 71 | ```shell 72 | git rebase master -i 73 | git push -f 74 | ``` 75 | 76 | That's it! Thank you for your contribution! 77 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | description: "A collection of Azure PowerShell code samples used in Microsoft's official Azure PowerShell Documentation." 4 | languages: 5 | - powershell 6 | products: 7 | - azure 8 | --- 9 | 10 | # Sample code used in Microsoft's official Azure PowerShell documentation 11 | 12 | All code in this repository is non-production samples used in Microsoft's official Azure PowerShell 13 | documentation and is designed to be used by our customers for learning and experimentation purposes. 14 | 15 | ## Microsoft Open Source Code of Conduct 16 | 17 | This repository has adopted the [Microsoft Open Source Code of Conduct][code-of-conduct]. 18 | 19 | ## Contributing 20 | 21 | > Note: this repository is only for Azure PowerShell code samples that reside in Microsoft's 22 | > official Azure PowerShell documentation on [learn.microsoft.com][ms-docs]. 23 | 24 | We welcome contributions to this repository via pull requests. Contributions must meet the following 25 | guidelines: 26 | 27 | - **Documentation use only:** Non-production samples used in Microsoft's official Azure PowerShell 28 | documentation. 29 | - **Azure PowerShell use only:** Contain commands from the Az PowerShell module. 30 | - **Sample scripts only:** Samples don't contain PowerShell modules (`psm1` files), binaries, tools, 31 | images, `zip` or `tar.gz` files, or other files that aren't samples. 32 | - **Validated samples:** Validate your samples using the latest version of the Az PowerShell module. 33 | - **Ongoing support:** Provide ongoing support for your samples and promptly respond to issues and 34 | PRs. 35 | 36 | Please note that before we can accept your pull request you must sign our 37 | [Contribution License Agreement][cla]. This is a one-time requirement. 38 | 39 | ## License 40 | 41 | The MIT License applies to the code contained in this repo. For more information, see 42 | [LICENSE][license]. 43 | 44 | 45 | 46 | [code-of-conduct]: CODE_OF_CONDUCT.md 47 | [ms-docs]: https://learn.microsoft.com/ 48 | [cla]: https://cla.microsoft.com/ 49 | [license]: LICENSE.md 50 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /azure-portal/portal-dashboard-template-testvm.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "lenses": [ 4 | { 5 | "order": 0, 6 | "parts": [ 7 | { 8 | "position": { 9 | "x": 0, 10 | "y": 0, 11 | "rowSpan": 2, 12 | "colSpan": 3 13 | }, 14 | "metadata": { 15 | "inputs": [], 16 | "type": "Extension[azure]/HubsExtension/PartType/MarkdownPart", 17 | "settings": { 18 | "content": { 19 | "settings": { 20 | "content": "## Azure Virtual Machines Overview\r\nNew team members should watch this video to get familiar with Azure Virtual Machines.", 21 | "title": "", 22 | "subtitle": "" 23 | } 24 | } 25 | } 26 | } 27 | }, 28 | { 29 | "position": { 30 | "x": 3, 31 | "y": 0, 32 | "rowSpan": 4, 33 | "colSpan": 8 34 | }, 35 | "metadata": { 36 | "inputs": [], 37 | "type": "Extension[azure]/HubsExtension/PartType/MarkdownPart", 38 | "settings": { 39 | "content": { 40 | "settings": { 41 | "content": "This is the team dashboard for the test VM we use on our team. Here are some useful links:\r\n\r\n1. [Azure portal documentation](https://docs.microsoft.com/azure/azure-portal/)\r\n1. [The structure of Azure Dashboards](https://docs.microsoft.com/azure/azure-portal/azure-portal-dashboards-structure)\r\n1. [Microsoft Azure PowerShell: Portal Dashboard cmdlets](https://docs.microsoft.com/powershell/module/Az.Portal/)", 42 | "title": "", 43 | "subtitle": "Test SubTitle" 44 | } 45 | } 46 | } 47 | } 48 | }, 49 | { 50 | "position": { 51 | "x": 0, 52 | "y": 2, 53 | "rowSpan": 2, 54 | "colSpan": 3 55 | }, 56 | "metadata": { 57 | "inputs": [], 58 | "type": "Extension[azure]/HubsExtension/PartType/VideoPart", 59 | "settings": { 60 | "content": { 61 | "settings": { 62 | "title": "", 63 | "subtitle": "", 64 | "src": "https://www.youtube.com/watch?v=GetnBRKNXco", 65 | "autoplay": false 66 | } 67 | } 68 | } 69 | } 70 | }, 71 | { 72 | "position": { 73 | "x": 0, 74 | "y": 4, 75 | "rowSpan": 3, 76 | "colSpan": 11 77 | }, 78 | "metadata": { 79 | "inputs": [ 80 | { 81 | "name": "queryInputs", 82 | "value": { 83 | "timespan": { 84 | "duration": "PT1H", 85 | "start": null, 86 | "end": null 87 | }, 88 | "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/", 89 | "chartType": 0, 90 | "metrics": [ 91 | { 92 | "name": "Percentage CPU", 93 | "resourceId": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 94 | } 95 | ] 96 | } 97 | } 98 | ], 99 | "type": "Extension/Microsoft_Azure_Monitoring/PartType/MetricsChartPart", 100 | "settings": {} 101 | } 102 | }, 103 | { 104 | "position": { 105 | "x": 0, 106 | "y": 7, 107 | "rowSpan": 2, 108 | "colSpan": 3 109 | }, 110 | "metadata": { 111 | "inputs": [ 112 | { 113 | "name": "queryInputs", 114 | "value": { 115 | "timespan": { 116 | "duration": "PT1H", 117 | "start": null, 118 | "end": null 119 | }, 120 | "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/", 121 | "chartType": 0, 122 | "metrics": [ 123 | { 124 | "name": "Disk Read Operations/Sec", 125 | "resourceId": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 126 | }, 127 | { 128 | "name": "Disk Write Operations/Sec", 129 | "resourceId": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 130 | } 131 | ] 132 | } 133 | } 134 | ], 135 | "type": "Extension/Microsoft_Azure_Monitoring/PartType/MetricsChartPart", 136 | "settings": {} 137 | } 138 | }, 139 | { 140 | "position": { 141 | "x": 3, 142 | "y": 7, 143 | "rowSpan": 2, 144 | "colSpan": 3 145 | }, 146 | "metadata": { 147 | "inputs": [ 148 | { 149 | "name": "queryInputs", 150 | "value": { 151 | "timespan": { 152 | "duration": "PT1H", 153 | "start": null, 154 | "end": null 155 | }, 156 | "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/", 157 | "chartType": 0, 158 | "metrics": [ 159 | { 160 | "name": "Disk Read Bytes", 161 | "resourceId": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 162 | }, 163 | { 164 | "name": "Disk Write Bytes", 165 | "resourceId": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 166 | } 167 | ] 168 | } 169 | } 170 | ], 171 | "type": "Extension/Microsoft_Azure_Monitoring/PartType/MetricsChartPart", 172 | "settings": {} 173 | } 174 | }, 175 | { 176 | "position": { 177 | "x": 6, 178 | "y": 7, 179 | "rowSpan": 2, 180 | "colSpan": 3 181 | }, 182 | "metadata": { 183 | "inputs": [ 184 | { 185 | "name": "queryInputs", 186 | "value": { 187 | "timespan": { 188 | "duration": "PT1H", 189 | "start": null, 190 | "end": null 191 | }, 192 | "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/", 193 | "chartType": 0, 194 | "metrics": [ 195 | { 196 | "name": "Network In", 197 | "resourceId": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 198 | }, 199 | { 200 | "name": "Network Out", 201 | "resourceId": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 202 | } 203 | ] 204 | } 205 | } 206 | ], 207 | "type": "Extension/Microsoft_Azure_Monitoring/PartType/MetricsChartPart", 208 | "settings": {} 209 | } 210 | }, 211 | { 212 | "position": { 213 | "x": 9, 214 | "y": 7, 215 | "rowSpan": 2, 216 | "colSpan": 2 217 | }, 218 | "metadata": { 219 | "inputs": [ 220 | { 221 | "name": "id", 222 | "value": "/subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/" 223 | } 224 | ], 225 | "type": "Extension/Microsoft_Azure_Compute/PartType/VirtualMachinePart", 226 | "asset": { 227 | "idInputName": "id", 228 | "type": "VirtualMachine" 229 | }, 230 | "defaultMenuItemId": "overview" 231 | } 232 | } 233 | ] 234 | } 235 | ], 236 | "metadata": { 237 | "model": { 238 | "timeRange": { 239 | "value": { 240 | "relative": { 241 | "duration": 24, 242 | "timeUnit": 1 243 | } 244 | }, 245 | "type": "MsPortalFx.Composition.Configuration.ValueTypes.TimeRange" 246 | } 247 | } 248 | } 249 | }, 250 | "id": "/subscriptions//resourceGroups/dashboards/providers/Microsoft.Portal/dashboards/5f4c6d95-06c3-4d03-bea2-1ca1b729ae33", 251 | "name": "5f4c6d95-06c3-4d03-bea2-1ca1b729ae33", 252 | "type": "Microsoft.Portal/dashboards", 253 | "location": "", 254 | "tags": { 255 | "hidden-title": "" 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /azure-sql/database/failover-groups/add-elastic-pool-to-failover-group-az-ps.ps1: -------------------------------------------------------------------------------- 1 |  2 | # 3 | # Add an elastic pool in Azure SQL Database to a failover group 4 | 5 | # 6 | 7 | # Set variables for your server and database 8 | $subscriptionId = '' 9 | $randomIdentifier = $(Get-Random) 10 | $resourceGroupName = "myResourceGroup-$randomIdentifier" 11 | $location = "East US" 12 | $adminLogin = "azureuser" 13 | $password = "PWD27!"+(New-Guid).Guid 14 | $serverName = "mysqlserver-$randomIdentifier" 15 | $poolName = "myElasticPool" 16 | $databaseName = "mySampleDatabase" 17 | $drLocation = "West US" 18 | $drServerName = "mysqlsecondary-$randomIdentifier" 19 | $failoverGroupName = "failovergrouptutorial-$randomIdentifier" 20 | 21 | 22 | # The ip address range that you want to allow to access your server 23 | # Leaving at 0.0.0.0 will prevent outside-of-azure connections 24 | $startIp = "0.0.0.0" 25 | $endIp = "0.0.0.0" 26 | 27 | # Show randomized variables 28 | Write-host "Resource group name is" $resourceGroupName 29 | Write-host "Password is" $password 30 | Write-host "Server name is" $serverName 31 | Write-host "DR Server name is" $drServerName 32 | Write-host "Failover group name is" $failoverGroupName 33 | 34 | # 35 | 36 | # 37 | 38 | # Set subscription ID 39 | Set-AzContext -SubscriptionId $subscriptionId 40 | 41 | # Create a resource group 42 | Write-host "Creating resource group..." 43 | $resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location -Tag @{Owner="SQLDB-Samples"} 44 | $resourceGroup 45 | 46 | # 47 | 48 | # 49 | 50 | # Create a server with a system-wide unique server name 51 | Write-host "Creating primary logical server..." 52 | New-AzSqlServer -ResourceGroupName $resourceGroupName ` 53 | -ServerName $serverName ` 54 | -Location $location ` 55 | -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential ` 56 | -ArgumentList $adminLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force)) 57 | Write-host "Primary logical server = " $serverName 58 | 59 | # Create a server firewall rule that allows access from the specified IP range 60 | Write-host "Configuring firewall for primary logical server..." 61 | New-AzSqlServerFirewallRule -ResourceGroupName $resourceGroupName ` 62 | -ServerName $serverName ` 63 | -FirewallRuleName "AllowedIPs" -StartIpAddress $startIp -EndIpAddress $endIp 64 | Write-host "Firewall configured" 65 | 66 | # Create General Purpose Gen5 database with 2 vCore 67 | Write-host "Creating a gen5 2 vCore database..." 68 | $database = New-AzSqlDatabase -ResourceGroupName $resourceGroupName ` 69 | -ServerName $serverName ` 70 | -DatabaseName $databaseName ` 71 | -Edition "GeneralPurpose" ` 72 | -VCore 2 ` 73 | -ComputeGeneration Gen5 ` 74 | -MinimumCapacity 1 ` 75 | -SampleName "AdventureWorksLT" 76 | $database 77 | 78 | # Create primary Gen5 elastic 2 vCore pool 79 | Write-host "Creating elastic pool..." 80 | $elasticPool = New-AzSqlElasticPool -ResourceGroupName $resourceGroupName ` 81 | -ServerName $serverName ` 82 | -ElasticPoolName $poolName ` 83 | -Edition "GeneralPurpose" ` 84 | -vCore 2 ` 85 | -ComputeGeneration Gen5 86 | $elasticPool 87 | 88 | # Add single db into elastic pool 89 | Write-host "Creating elastic pool..." 90 | $addDatabase = Set-AzSqlDatabase -ResourceGroupName $resourceGroupName ` 91 | -ServerName $serverName ` 92 | -DatabaseName $databaseName ` 93 | -ElasticPoolName $poolName 94 | $addDatabase 95 | 96 | # 97 | 98 | # 99 | 100 | # Create a secondary server in the failover region 101 | Write-host "Creating a secondary logical server in the failover region..." 102 | New-AzSqlServer -ResourceGroupName $resourceGroupName ` 103 | -ServerName $drServerName ` 104 | -Location $drLocation ` 105 | -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential ` 106 | -ArgumentList $adminlogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force)) 107 | Write-host "Secondary logical server =" $drServerName 108 | 109 | # Create a server firewall rule that allows access from the specified IP range 110 | Write-host "Configuring firewall for secondary logical server..." 111 | New-AzSqlServerFirewallRule -ResourceGroupName $resourceGroupName ` 112 | -ServerName $drServerName ` 113 | -FirewallRuleName "AllowedIPs" -StartIpAddress $startIp -EndIpAddress $endIp 114 | Write-host "Firewall configured" 115 | 116 | # Create secondary Gen5 elastic 2 vCore pool 117 | Write-host "Creating secondary elastic pool..." 118 | $elasticPool = New-AzSqlElasticPool -ResourceGroupName $resourceGroupName ` 119 | -ServerName $drServerName ` 120 | -ElasticPoolName $poolName ` 121 | -Edition "GeneralPurpose" ` 122 | -vCore 2 ` 123 | -ComputeGeneration Gen5 124 | $elasticPool 125 | 126 | # 127 | 128 | # 129 | 130 | # Create a failover group between the servers 131 | Write-host "Creating failover group..." 132 | New-AzSqlDatabaseFailoverGroup ` 133 | –ResourceGroupName $resourceGroupName ` 134 | -ServerName $serverName ` 135 | -PartnerServerName $drServerName ` 136 | –FailoverGroupName $failoverGroupName ` 137 | –FailoverPolicy Manual 138 | Write-host "Failover group created successfully." 139 | 140 | # 141 | 142 | # 143 | 144 | # Add elastic pool to the failover group 145 | Write-host "Enumerating databases in elastic pool...." 146 | $FailoverGroup = Get-AzSqlDatabaseFailoverGroup ` 147 | -ResourceGroupName $resourceGroupName ` 148 | -ServerName $serverName ` 149 | -FailoverGroupName $failoverGroupName 150 | $databases = Get-AzSqlElasticPoolDatabase ` 151 | -ResourceGroupName $resourceGroupName ` 152 | -ServerName $serverName ` 153 | -ElasticPoolName $poolName 154 | Write-host "Adding databases to failover group..." 155 | $failoverGroup = $failoverGroup | Add-AzSqlDatabaseToFailoverGroup ` 156 | -Database $databases 157 | $failoverGroup 158 | 159 | # 160 | 161 | # 162 | 163 | # Check role of secondary replica 164 | Write-host "Confirming the secondary server is secondary...." 165 | (Get-AzSqlDatabaseFailoverGroup ` 166 | -FailoverGroupName $failoverGroupName ` 167 | -ResourceGroupName $resourceGroupName ` 168 | -ServerName $drServerName).ReplicationRole 169 | 170 | # 171 | 172 | # 173 | # Failover to secondary server 174 | Write-host "Failing over failover group to the secondary..." 175 | Switch-AzSqlDatabaseFailoverGroup ` 176 | -ResourceGroupName $resourceGroupName ` 177 | -ServerName $drServerName ` 178 | -FailoverGroupName $failoverGroupName 179 | Write-host "Failover group failed over to" $drServerName 180 | 181 | # Check role of secondary replica 182 | Write-host "Confirming the secondary server is now primary" 183 | (Get-AzSqlDatabaseFailoverGroup ` 184 | -FailoverGroupName $failoverGroupName ` 185 | -ResourceGroupName $resourceGroupName ` 186 | -ServerName $drServerName).ReplicationRole 187 | 188 | # 189 | 190 | # 191 | 192 | # Revert failover to primary server 193 | Write-host "Failing over failover group to the primary...." 194 | Switch-AzSqlDatabaseFailoverGroup ` 195 | -ResourceGroupName $resourceGroupName ` 196 | -ServerName $serverName ` 197 | -FailoverGroupName $failoverGroupName 198 | Write-host "Failover group failed over to" $serverName 199 | 200 | # 201 | 202 | # Clean up resources by removing the resource group 203 | # Write-host "Removing resource group..." 204 | # Remove-AzResourceGroup -ResourceGroupName $resourceGroupName 205 | # Write-host "Resource group removed =" $resourceGroupName 206 | 207 | # -------------------------------------------------------------------------------- /azure-sql/database/failover-groups/add-single-db-to-failover-group-az-ps.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Add a single Azure SQL Database to a failover group 3 | 4 | # 5 | # Set variables for your server and database 6 | $subscriptionId = '' 7 | $randomIdentifier = $(Get-Random) 8 | $resourceGroupName = "myResourceGroup-$randomIdentifier" 9 | $location = "West US 2" 10 | $adminLogin = "azureuser" 11 | $password = "PWD27!"+(New-Guid).Guid 12 | $serverName = "mysqlserver-$randomIdentifier" 13 | $databaseName = "mySampleDatabase" 14 | $drLocation = "East US 2" 15 | $drServerName = "mysqlsecondary-$randomIdentifier" 16 | $failoverGroupName = "failovergrouptutorial-$randomIdentifier" 17 | 18 | 19 | # The ip address range that you want to allow to access your server 20 | # Leaving at 0.0.0.0 will prevent outside-of-azure connections 21 | $startIp = "0.0.0.0" 22 | $endIp = "0.0.0.0" 23 | 24 | # Show randomized variables 25 | Write-host "Resource group name is" $resourceGroupName 26 | Write-host "Password is" $password 27 | Write-host "Server name is" $serverName 28 | Write-host "DR Server name is" $drServerName 29 | Write-host "Failover group name is" $failoverGroupName 30 | 31 | # 32 | 33 | # 34 | 35 | # Set subscription ID 36 | Set-AzContext -SubscriptionId $subscriptionId 37 | 38 | # Create a resource group 39 | Write-host "Creating resource group..." 40 | $resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location -Tag @{Owner="SQLDB-Samples"} 41 | $resourceGroup 42 | 43 | # 44 | 45 | # 46 | 47 | # Create a server with a system wide unique server name 48 | Write-host "Creating primary logical server..." 49 | $server = New-AzSqlServer -ResourceGroupName $resourceGroupName ` 50 | -ServerName $serverName ` 51 | -Location $location ` 52 | -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential ` 53 | -ArgumentList $adminLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force)) 54 | $server 55 | 56 | # Create a server firewall rule that allows access from the specified IP range 57 | Write-host "Configuring firewall for primary logical server..." 58 | $serverFirewallRule = New-AzSqlServerFirewallRule -ResourceGroupName $resourceGroupName ` 59 | -ServerName $serverName ` 60 | -FirewallRuleName "AllowedIPs" -StartIpAddress $startIp -EndIpAddress $endIp 61 | $serverFirewallRule 62 | 63 | # Create General Purpose Gen5 database with 2 vCore 64 | Write-host "Creating a gen5 2 vCore database..." 65 | $database = New-AzSqlDatabase -ResourceGroupName $resourceGroupName ` 66 | -ServerName $serverName ` 67 | -DatabaseName $databaseName ` 68 | -Edition GeneralPurpose ` 69 | -VCore 2 ` 70 | -ComputeGeneration Gen5 ` 71 | -MinimumCapacity 2 ` 72 | -SampleName "AdventureWorksLT" 73 | $database 74 | 75 | # 76 | 77 | # 78 | 79 | # Create a secondary server in the failover region 80 | Write-host "Creating a secondary logical server in the failover region..." 81 | $drServer = New-AzSqlServer -ResourceGroupName $resourceGroupName ` 82 | -ServerName $drServerName ` 83 | -Location $drLocation ` 84 | -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential ` 85 | -ArgumentList $adminlogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force)) 86 | $drServer 87 | 88 | # 89 | 90 | # 91 | 92 | # Create a failover group between the servers 93 | $failovergroup = Write-host "Creating a failover group between the primary and secondary server..." 94 | New-AzSqlDatabaseFailoverGroup ` 95 | –ResourceGroupName $resourceGroupName ` 96 | -ServerName $serverName ` 97 | -PartnerServerName $drServerName ` 98 | –FailoverGroupName $failoverGroupName ` 99 | –FailoverPolicy Manual 100 | $failovergroup 101 | # 102 | 103 | # 104 | 105 | # Add the database to the failover group 106 | Write-host "Adding the database to the failover group..." 107 | Get-AzSqlDatabase ` 108 | -ResourceGroupName $resourceGroupName ` 109 | -ServerName $serverName ` 110 | -DatabaseName $databaseName | ` 111 | Add-AzSqlDatabaseToFailoverGroup ` 112 | -ResourceGroupName $resourceGroupName ` 113 | -ServerName $serverName ` 114 | -FailoverGroupName $failoverGroupName 115 | Write-host "Successfully added the database to the failover group..." 116 | 117 | # 118 | 119 | # 120 | 121 | # Check role of secondary replica 122 | Write-host "Confirming the secondary replica is secondary...." 123 | (Get-AzSqlDatabaseFailoverGroup ` 124 | -FailoverGroupName $failoverGroupName ` 125 | -ResourceGroupName $resourceGroupName ` 126 | -ServerName $drServerName).ReplicationRole 127 | 128 | # 129 | 130 | 131 | # 132 | 133 | # Failover to secondary server 134 | Write-host "Failing over failover group to the secondary..." 135 | Switch-AzSqlDatabaseFailoverGroup ` 136 | -ResourceGroupName $resourceGroupName ` 137 | -ServerName $drServerName ` 138 | -FailoverGroupName $failoverGroupName 139 | Write-host "Failed failover group successfully to" $drServerName 140 | 141 | Write-host "Confirming the secondary server is now primary...." 142 | (Get-AzSqlDatabaseFailoverGroup ` 143 | -FailoverGroupName $failoverGroupName ` 144 | -ResourceGroupName $resourceGroupName ` 145 | -ServerName $drServerName).ReplicationRole 146 | 147 | # 148 | 149 | # 150 | 151 | # Revert failover to primary server 152 | Write-host "Failing over failover group to the primary...." 153 | Switch-AzSqlDatabaseFailoverGroup ` 154 | -ResourceGroupName $resourceGroupName ` 155 | -ServerName $serverName ` 156 | -FailoverGroupName $failoverGroupName 157 | Write-host "Failed failover group successfully back to" $serverName 158 | 159 | # 160 | 161 | # Show randomized variables 162 | Write-host "Resource group name is" $resourceGroupName 163 | Write-host "Password is" $password 164 | Write-host "Server name is" $serverName 165 | Write-host "DR Server name is" $drServerName 166 | Write-host "Failover group name is" $failoverGroupName 167 | 168 | # Clean up resources by removing the resource group 169 | # Write-host "Removing resource group..." 170 | # Remove-AzResourceGroup -ResourceGroupName $resourceGroupName 171 | # Write-host "Resource group removed =" $resourceGroupName 172 | 173 | # -------------------------------------------------------------------------------- /azure-sql/managed-instance/create-and-configure-managed-instance.ps1: -------------------------------------------------------------------------------- 1 | # 2 | $NSnetworkModels = "Microsoft.Azure.Commands.Network.Models" 3 | $NScollections = "System.Collections.Generic" 4 | 5 | # The SubscriptionId in which to create these objects 6 | $SubscriptionId = '' 7 | # Set the resource group name and location for your managed instance 8 | $resourceGroupName = "myResourceGroup-$(Get-Random)" 9 | $location = "eastus2" 10 | # Set the networking values for your managed instance 11 | $vNetName = "myVnet-$(Get-Random)" 12 | $vNetAddressPrefix = "10.0.0.0/16" 13 | $defaultSubnetName = "myDefaultSubnet-$(Get-Random)" 14 | $defaultSubnetAddressPrefix = "10.0.0.0/24" 15 | $miSubnetName = "MISubnet-$(Get-Random)" 16 | $miSubnetAddressPrefix = "10.0.0.0/24" 17 | #Set the managed instance name for the new managed instance 18 | $instanceName = "mi-name-$(Get-Random)" 19 | # Set the admin login and password for your managed instance 20 | $miAdminSqlLogin = "SqlAdmin" 21 | $miAdminSqlPassword = "ChangeThisPassword!!" 22 | # Set the managed instance service tier, compute level, and license mode 23 | $edition = "General Purpose" 24 | $vCores = 8 25 | $maxStorage = 256 26 | $computeGeneration = "Gen5" 27 | $license = "LicenseIncluded" #"BasePrice" or LicenseIncluded if you have don't have SQL Server licence that can be used for AHB discount 28 | $dbname = 'SampleDB' 29 | 30 | # 31 | 32 | # 33 | 34 | # Set subscription context 35 | Connect-AzAccount 36 | $subscriptionContextParams = @{ 37 | SubscriptionId = $SubscriptionId 38 | } 39 | Set-AzContext @subscriptionContextParams 40 | 41 | # Create a resource group 42 | $resourceGroupParams = @{ 43 | Name = $resourceGroupName 44 | Location = $location 45 | Tag = @{Owner="SQLDB-Samples"} 46 | } 47 | $resourceGroup = New-AzResourceGroup @resourceGroupParams 48 | 49 | # 50 | 51 | # 52 | 53 | # Configure virtual network, subnets, network security group, and routing table 54 | $networkSecurityGroupParams = @{ 55 | Name = 'myNetworkSecurityGroupMiManagementService' 56 | ResourceGroupName = $resourceGroupName 57 | Location = $location 58 | } 59 | $networkSecurityGroupMiManagementService = New-AzNetworkSecurityGroup @networkSecurityGroupParams 60 | 61 | $routeTableParams = @{ 62 | Name = 'myRouteTableMiManagementService' 63 | ResourceGroupName = $resourceGroupName 64 | Location = $location 65 | } 66 | $routeTableMiManagementService = New-AzRouteTable @routeTableParams 67 | 68 | $virtualNetworkParams = @{ 69 | ResourceGroupName = $resourceGroupName 70 | Location = $location 71 | Name = $vNetName 72 | AddressPrefix = $vNetAddressPrefix 73 | } 74 | 75 | $virtualNetwork = New-AzVirtualNetwork @virtualNetworkParams 76 | 77 | $subnetConfigParams = @{ 78 | Name = $miSubnetName 79 | VirtualNetwork = $virtualNetwork 80 | AddressPrefix = $miSubnetAddressPrefix 81 | NetworkSecurityGroup = $networkSecurityGroupMiManagementService 82 | RouteTable = $routeTableMiManagementService 83 | } 84 | 85 | $subnetConfig = Add-AzVirtualNetworkSubnetConfig @subnetConfigParams | Set-AzVirtualNetwork 86 | 87 | $virtualNetwork = Get-AzVirtualNetwork -Name $vNetName -ResourceGroupName $resourceGroupName 88 | 89 | $subnet= $virtualNetwork.Subnets[0] 90 | 91 | # Create a delegation 92 | $subnet.Delegations = New-Object "$NScollections.List``1[$NSnetworkModels.PSDelegation]" 93 | $delegationName = "dgManagedInstance" + (Get-Random -Maximum 1000) 94 | $delegationParams = @{ 95 | Name = $delegationName 96 | ServiceName = "Microsoft.Sql/managedInstances" 97 | } 98 | $delegation = New-AzDelegation @delegationParams 99 | $subnet.Delegations.Add($delegation) 100 | 101 | Set-AzVirtualNetwork -VirtualNetwork $virtualNetwork 102 | 103 | $miSubnetConfigId = $subnet.Id 104 | 105 | $allowParameters = @{ 106 | Access = 'Allow' 107 | Protocol = 'Tcp' 108 | Direction= 'Inbound' 109 | SourcePortRange = '*' 110 | SourceAddressPrefix = 'VirtualNetwork' 111 | DestinationAddressPrefix = '*' 112 | } 113 | $denyInParameters = @{ 114 | Access = 'Deny' 115 | Protocol = '*' 116 | Direction = 'Inbound' 117 | SourcePortRange = '*' 118 | SourceAddressPrefix = '*' 119 | DestinationPortRange = '*' 120 | DestinationAddressPrefix = '*' 121 | } 122 | $denyOutParameters = @{ 123 | Access = 'Deny' 124 | Protocol = '*' 125 | Direction = 'Outbound' 126 | SourcePortRange = '*' 127 | SourceAddressPrefix = '*' 128 | DestinationPortRange = '*' 129 | DestinationAddressPrefix = '*' 130 | } 131 | 132 | $networkSecurityGroupParams = @{ 133 | ResourceGroupName = $resourceGroupName 134 | Name = "myNetworkSecurityGroupMiManagementService" 135 | } 136 | 137 | $networkSecurityGroup = Get-AzNetworkSecurityGroup @networkSecurityGroupParams 138 | 139 | $allowRuleParams = @{ 140 | Access = 'Allow' 141 | Protocol = 'Tcp' 142 | Direction = 'Inbound' 143 | SourcePortRange = '*' 144 | SourceAddressPrefix = 'VirtualNetwork' 145 | DestinationAddressPrefix = '*' 146 | } 147 | 148 | $denyInRuleParams = @{ 149 | Access = 'Deny' 150 | Protocol = '*' 151 | Direction = 'Inbound' 152 | SourcePortRange = '*' 153 | SourceAddressPrefix = '*' 154 | DestinationPortRange = '*' 155 | DestinationAddressPrefix = '*' 156 | } 157 | 158 | $denyOutRuleParams = @{ 159 | Access = 'Deny' 160 | Protocol = '*' 161 | Direction = 'Outbound' 162 | SourcePortRange = '*' 163 | SourceAddressPrefix = '*' 164 | DestinationPortRange = '*' 165 | DestinationAddressPrefix = '*' 166 | } 167 | 168 | $networkSecurityGroup | 169 | Add-AzNetworkSecurityRuleConfig @allowRuleParams -Priority 1000 -Name "allow_tds_inbound" -DestinationPortRange 1433 | 170 | Add-AzNetworkSecurityRuleConfig @allowRuleParams -Priority 1100 -Name "allow_redirect_inbound" -DestinationPortRange 11000-11999 | 171 | Add-AzNetworkSecurityRuleConfig @denyInRuleParams -Priority 4096 -Name "deny_all_inbound" | 172 | Add-AzNetworkSecurityRuleConfig @denyOutRuleParams -Priority 4096 -Name "deny_all_outbound" | 173 | Set-AzNetworkSecurityGroup 174 | 175 | 176 | # 177 | 178 | # 179 | 180 | # Create credentials 181 | $secpassword = ConvertTo-SecureString $miAdminSqlPassword -AsPlainText -Force 182 | $credential = New-Object System.Management.Automation.PSCredential -ArgumentList @($miAdminSqlLogin, $secpassword) 183 | 184 | $managedInstanceParams = @{ 185 | Name = $instanceName 186 | ResourceGroupName = $resourceGroupName 187 | Location = $location 188 | SubnetId = $miSubnetConfigId 189 | AdministratorCredential = $credential 190 | StorageSizeInGB = $maxStorage 191 | VCore = $vCores 192 | Edition = $edition 193 | ComputeGeneration = $computeGeneration 194 | LicenseType = $license 195 | } 196 | 197 | New-AzSqlInstance @managedInstanceParams 198 | 199 | # 200 | 201 | # 202 | 203 | $databaseParams = @{ 204 | ResourceGroupName = $resourceGroupName 205 | InstanceName = $instanceName 206 | Name = $dbname 207 | Collation = 'Latin1_General_100_CS_AS_SC' 208 | } 209 | 210 | New-AzSqlInstanceDatabase @databaseParams 211 | 212 | # 213 | 214 | # Clean up deployment  215 | # Remove-AzResourceGroup -ResourceGroupName $resourceGroupName 216 | -------------------------------------------------------------------------------- /azure-sql/managed-instance/failover-groups/add-managed-instance-to-failover-group-az-ps.ps1: -------------------------------------------------------------------------------- 1 |  2 | # 3 | # Add SQL Managed Instance to a failover group 4 | 5 | <# 6 | Due to SQL Managed Instance deployment times, plan for a full day to complete the entire script. 7 | You can monitor deployment progress in the activity log within the Azure portal. 8 | 9 | For more information on deployment times, see https://learn.microsoft.com/azure/azure-sql/managed-instance/management-operations-overview. 10 | 11 | Closing the session will result in an incomplete deployment. To continue progress, you will 12 | need to determine what the random modifier is and manually replace the random variable with 13 | the previously-assigned value. 14 | #> 15 | 16 | <# 17 | ============================================================================================= 18 | The following sets all the parameters for the two SQL managed instances, and failover group. 19 | ============================================================================================ 20 | #> 21 | 22 | # 23 | 24 | # The SubscriptionId in which to create these objects 25 | $SubscriptionId = '' 26 | # Create a random identifier to use as subscript for the different resource names 27 | $randomIdentifier = $(Get-Random) 28 | # Set the resource group name and location for SQL Managed Instance 29 | $resourceGroupName = "myResourceGroup-$randomIdentifier" 30 | $location = "eastus" 31 | $drLocation = "southcentralus" 32 | 33 | # Set the networking values for your primary managed instance 34 | $primaryVNet = "primaryVNet-$randomIdentifier" 35 | $primaryAddressPrefix = "10.0.0.0/16" 36 | $primaryDefaultSubnet = "primaryDefaultSubnet-$randomIdentifier" 37 | $primaryDefaultSubnetAddress = "10.0.0.0/24" 38 | $primaryMiSubnetName = "primaryMISubnet-$randomIdentifier" 39 | $primaryMiSubnetAddress = "10.0.0.0/24" 40 | $primaryMiGwSubnetAddress = "10.0.255.0/27" 41 | $primaryGWName = "primaryGateway-$randomIdentifier" 42 | $primaryGWPublicIPAddress = $primaryGWName + "-ip" 43 | $primaryGWIPConfig = $primaryGWName + "-ipc" 44 | $primaryGWAsn = 61000 45 | $primaryGWConnection = $primaryGWName + "-connection" 46 | 47 | 48 | # Set the networking values for your secondary managed instance 49 | $secondaryVNet = "secondaryVNet-$randomIdentifier" 50 | $secondaryAddressPrefix = "10.128.0.0/16" 51 | $secondaryDefaultSubnet = "secondaryDefaultSubnet-$randomIdentifier" 52 | $secondaryDefaultSubnetAddress = "10.128.0.0/24" 53 | $secondaryMiSubnetName = "secondaryMISubnet-$randomIdentifier" 54 | $secondaryMiSubnetAddress = "10.128.0.0/24" 55 | $secondaryMiGwSubnetAddress = "10.128.255.0/27" 56 | $secondaryGWName = "secondaryGateway-$randomIdentifier" 57 | $secondaryGWPublicIPAddress = $secondaryGWName + "-IP" 58 | $secondaryGWIPConfig = $secondaryGWName + "-ipc" 59 | $secondaryGWAsn = 62000 60 | $secondaryGWConnection = $secondaryGWName + "-connection" 61 | 62 | # Set the SQL Managed Instance name for the new managed instances 63 | $primaryInstance = "primary-mi-$randomIdentifier" 64 | $secondaryInstance = "secondary-mi-$randomIdentifier" 65 | 66 | # Set the admin login and password for SQL Managed Instance 67 | $secpasswd = "PWD27!"+(New-Guid).Guid | ConvertTo-SecureString -AsPlainText -Force 68 | $mycreds = New-Object System.Management.Automation.PSCredential ("azureuser", $secpasswd) 69 | 70 | # Set the SQL Managed Instance service tier, compute level, and license mode 71 | $edition = "General Purpose" 72 | $vCores = 8 73 | $maxStorage = 256 74 | $computeGeneration = "Gen5" 75 | $license = "LicenseIncluded" #"BasePrice" or LicenseIncluded if you have don't have SQL Server license that can be used for AHB discount 76 | 77 | # Set failover group details 78 | $vpnSharedKey = "mi1mi2psk" 79 | $failoverGroupName = "failovergroup-$randomIdentifier" 80 | 81 | # Show randomized variables 82 | Write-host "Resource group name is" $resourceGroupName 83 | Write-host "Password is" $secpasswd 84 | Write-host "Primary Virtual Network name is" $primaryVNet 85 | Write-host "Primary default subnet name is" $primaryDefaultSubnet 86 | Write-host "Primary SQL Managed Instance subnet name is" $primaryMiSubnetName 87 | Write-host "Secondary Virtual Network name is" $secondaryVNet 88 | Write-host "Secondary default subnet name is" $secondaryDefaultSubnet 89 | Write-host "Secondary SQL Managed Instance subnet name is" $secondaryMiSubnetName 90 | Write-host "Primary SQL Managed Instance name is" $primaryInstance 91 | Write-host "Secondary SQL Managed Instance name is" $secondaryInstance 92 | Write-host "Failover group name is" $failoverGroupName 93 | 94 | # 95 | 96 | <#=========================================================================== 97 | The following sets your subscription context and creates the resource group 98 | ==========================================================================#> 99 | 100 | # 101 | 102 | # Suppress networking breaking changes warning (https://aka.ms/azps-changewarnings 103 | Set-Item Env:\SuppressAzurePowerShellBreakingChangeWarnings "true" 104 | 105 | # Set the subscription context 106 | Set-AzContext -SubscriptionId $subscriptionId 107 | 108 | # Create the resource group 109 | Write-host "Creating resource group..." 110 | $resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location -Tag @{Owner="SQLDB-Samples"} 111 | $resourceGroup 112 | 113 | # 114 | 115 | <#=========================================================================== 116 | The following configures resources for the primary SQL Managed Instance 117 | ===========================================================================#> 118 | 119 | # 120 | 121 | # Configure the primary virtual network 122 | Write-host "Creating primary virtual network..." 123 | $primarySubnetDelegation = New-AzDelegation -Name "ManagedInstance" -ServiceName "Microsoft.Sql/managedInstances" 124 | $primaryVirtualNetwork = New-AzVirtualNetwork ` 125 | -ResourceGroupName $resourceGroupName ` 126 | -Location $location ` 127 | -Name $primaryVNet ` 128 | -AddressPrefix $primaryAddressPrefix 129 | Add-AzVirtualNetworkSubnetConfig ` 130 | -Name $primaryMiSubnetName ` 131 | -VirtualNetwork $primaryVirtualNetwork ` 132 | -AddressPrefix $PrimaryMiSubnetAddress ` 133 | -Delegation $primarySubnetDelegation ` 134 | | Set-AzVirtualNetwork 135 | $primaryVirtualNetwork 136 | Write-host "Primary virtual network created successfully." 137 | 138 | 139 | # Configure the primary managed instance subnet 140 | Write-host "Configuring primary MI subnet..." 141 | $primaryVirtualNetwork = Get-AzVirtualNetwork -Name $primaryVNet -ResourceGroupName $resourceGroupName 142 | 143 | 144 | $primaryMiSubnetConfig = Get-AzVirtualNetworkSubnetConfig ` 145 | -Name $primaryMiSubnetName ` 146 | -VirtualNetwork $primaryVirtualNetwork 147 | $primaryMiSubnetConfig 148 | Write-host "Primary MI subnet configured successfully." 149 | 150 | 151 | # Configure the network security group management service 152 | Write-host "Configuring primary MI network security group..." 153 | 154 | $primaryMiSubnetConfigId = $primaryMiSubnetConfig.Id 155 | 156 | $primaryNSGMiManagementService = New-AzNetworkSecurityGroup ` 157 | -Name 'primaryNSGMiManagementService' ` 158 | -ResourceGroupName $resourceGroupName ` 159 | -location $location 160 | $primaryNSGMiManagementService 161 | Write-host "Primary MI network security group configured successfully." 162 | 163 | 164 | # Configure the route table management service 165 | Write-host "Configuring primary MI route table management service..." 166 | 167 | $primaryRouteTableMiManagementService = New-AzRouteTable ` 168 | -Name 'primaryRouteTableMiManagementService' ` 169 | -ResourceGroupName $resourceGroupName ` 170 | -location $location 171 | $primaryRouteTableMiManagementService 172 | Write-host "Primary MI route table management service configured successfully." 173 | 174 | 175 | # Configure the primary network security group 176 | Write-host "Configuring primary network security group..." 177 | Set-AzVirtualNetworkSubnetConfig ` 178 | -VirtualNetwork $primaryVirtualNetwork ` 179 | -Name $primaryMiSubnetName ` 180 | -AddressPrefix $PrimaryMiSubnetAddress ` 181 | -NetworkSecurityGroup $primaryNSGMiManagementService ` 182 | -RouteTable $primaryRouteTableMiManagementService ` 183 | -Delegation $primarySubnetDelegation ` 184 | | Set-AzVirtualNetwork 185 | 186 | Get-AzNetworkSecurityGroup ` 187 | -ResourceGroupName $resourceGroupName ` 188 | -Name "primaryNSGMiManagementService" ` 189 | | Add-AzNetworkSecurityRuleConfig ` 190 | -Priority 100 ` 191 | -Name "allow_management_inbound" ` 192 | -Access Allow ` 193 | -Protocol Tcp ` 194 | -Direction Inbound ` 195 | -SourcePortRange * ` 196 | -SourceAddressPrefix * ` 197 | -DestinationPortRange 9000,9003,1438,1440,1452 ` 198 | -DestinationAddressPrefix * ` 199 | | Add-AzNetworkSecurityRuleConfig ` 200 | -Priority 200 ` 201 | -Name "allow_misubnet_inbound" ` 202 | -Access Allow ` 203 | -Protocol * ` 204 | -Direction Inbound ` 205 | -SourcePortRange * ` 206 | -SourceAddressPrefix $PrimaryMiSubnetAddress ` 207 | -DestinationPortRange * ` 208 | -DestinationAddressPrefix * ` 209 | | Add-AzNetworkSecurityRuleConfig ` 210 | -Priority 300 ` 211 | -Name "allow_health_probe_inbound" ` 212 | -Access Allow ` 213 | -Protocol * ` 214 | -Direction Inbound ` 215 | -SourcePortRange * ` 216 | -SourceAddressPrefix AzureLoadBalancer ` 217 | -DestinationPortRange * ` 218 | -DestinationAddressPrefix * ` 219 | | Add-AzNetworkSecurityRuleConfig ` 220 | -Priority 1000 ` 221 | -Name "allow_tds_inbound" ` 222 | -Access Allow ` 223 | -Protocol Tcp ` 224 | -Direction Inbound ` 225 | -SourcePortRange * ` 226 | -SourceAddressPrefix VirtualNetwork ` 227 | -DestinationPortRange 1433 ` 228 | -DestinationAddressPrefix * ` 229 | | Add-AzNetworkSecurityRuleConfig ` 230 | -Priority 1100 ` 231 | -Name "allow_redirect_inbound" ` 232 | -Access Allow ` 233 | -Protocol Tcp ` 234 | -Direction Inbound ` 235 | -SourcePortRange * ` 236 | -SourceAddressPrefix VirtualNetwork ` 237 | -DestinationPortRange 11000-11999 ` 238 | -DestinationAddressPrefix * ` 239 | | Add-AzNetworkSecurityRuleConfig ` 240 | -Priority 1200 ` 241 | -Name "allow_geodr_inbound" ` 242 | -Access Allow ` 243 | -Protocol Tcp ` 244 | -Direction Inbound ` 245 | -SourcePortRange * ` 246 | -SourceAddressPrefix VirtualNetwork ` 247 | -DestinationPortRange 5022 ` 248 | -DestinationAddressPrefix * ` 249 | | Add-AzNetworkSecurityRuleConfig ` 250 | -Priority 4096 ` 251 | -Name "deny_all_inbound" ` 252 | -Access Deny ` 253 | -Protocol * ` 254 | -Direction Inbound ` 255 | -SourcePortRange * ` 256 | -SourceAddressPrefix * ` 257 | -DestinationPortRange * ` 258 | -DestinationAddressPrefix * ` 259 | | Add-AzNetworkSecurityRuleConfig ` 260 | -Priority 100 ` 261 | -Name "allow_management_outbound" ` 262 | -Access Allow ` 263 | -Protocol Tcp ` 264 | -Direction Outbound ` 265 | -SourcePortRange * ` 266 | -SourceAddressPrefix * ` 267 | -DestinationPortRange 80,443,12000 ` 268 | -DestinationAddressPrefix * ` 269 | | Add-AzNetworkSecurityRuleConfig ` 270 | -Priority 200 ` 271 | -Name "allow_misubnet_outbound" ` 272 | -Access Allow ` 273 | -Protocol * ` 274 | -Direction Outbound ` 275 | -SourcePortRange * ` 276 | -SourceAddressPrefix * ` 277 | -DestinationPortRange * ` 278 | -DestinationAddressPrefix $PrimaryMiSubnetAddress ` 279 | | Add-AzNetworkSecurityRuleConfig ` 280 | -Priority 1100 ` 281 | -Name "allow_redirect_outbound" ` 282 | -Access Allow ` 283 | -Protocol Tcp ` 284 | -Direction Outbound ` 285 | -SourcePortRange * ` 286 | -SourceAddressPrefix VirtualNetwork ` 287 | -DestinationPortRange 11000-11999 ` 288 | -DestinationAddressPrefix * ` 289 | | Add-AzNetworkSecurityRuleConfig ` 290 | -Priority 1200 ` 291 | -Name "allow_geodr_outbound" ` 292 | -Access Allow ` 293 | -Protocol Tcp ` 294 | -Direction Outbound ` 295 | -SourcePortRange * ` 296 | -SourceAddressPrefix VirtualNetwork ` 297 | -DestinationPortRange 5022 ` 298 | -DestinationAddressPrefix * ` 299 | | Add-AzNetworkSecurityRuleConfig ` 300 | -Priority 4096 ` 301 | -Name "deny_all_outbound" ` 302 | -Access Deny ` 303 | -Protocol * ` 304 | -Direction Outbound ` 305 | -SourcePortRange * ` 306 | -SourceAddressPrefix * ` 307 | -DestinationPortRange * ` 308 | -DestinationAddressPrefix * ` 309 | | Set-AzNetworkSecurityGroup 310 | Write-host "Primary network security group configured successfully." 311 | 312 | # Configure the primary network route table 313 | Write-host "Configuring primary network route table..." 314 | Get-AzRouteTable ` 315 | -ResourceGroupName $resourceGroupName ` 316 | -Name "primaryRouteTableMiManagementService" ` 317 | | Add-AzRouteConfig ` 318 | -Name "primaryToMIManagementService" ` 319 | -AddressPrefix 0.0.0.0/0 ` 320 | -NextHopType Internet ` 321 | | Add-AzRouteConfig ` 322 | -Name "ToLocalClusterNode" ` 323 | -AddressPrefix $PrimaryMiSubnetAddress ` 324 | -NextHopType VnetLocal ` 325 | | Set-AzRouteTable 326 | Write-host "Primary network route table configured successfully." 327 | 328 | 329 | # Create the primary managed instance 330 | Write-host "Creating primary SQL Managed Instance..." 331 | Write-host "This will take some time, see https://learn.microsoft.com/azure/azure-sql/managed-instance/management-operations-overview for more information." 332 | New-AzSqlInstance -Name $primaryInstance ` 333 | -ResourceGroupName $resourceGroupName ` 334 | -Location $location ` 335 | -SubnetId $primaryMiSubnetConfigId ` 336 | -AdministratorCredential $mycreds ` 337 | -StorageSizeInGB $maxStorage ` 338 | -VCore $vCores ` 339 | -Edition $edition ` 340 | -ComputeGeneration $computeGeneration ` 341 | -LicenseType $license 342 | $primaryInstance 343 | Write-host "Primary SQL Managed Instance created successfully." 344 | 345 | # 346 | 347 | <#=========================================================================== 348 | The following configures resources for the secondary SQL Managed Instance 349 | ===========================================================================#> 350 | 351 | # 352 | 353 | # Configure the secondary virtual network 354 | Write-host "Configuring secondary virtual network..." 355 | $secondarySubnetDelegation = New-AzDelegation -Name "ManagedInstance" -ServiceName "Microsoft.Sql/managedInstances" 356 | $SecondaryVirtualNetwork = New-AzVirtualNetwork ` 357 | -ResourceGroupName $resourceGroupName ` 358 | -Location $drlocation ` 359 | -Name $secondaryVNet ` 360 | -AddressPrefix $secondaryAddressPrefix 361 | Add-AzVirtualNetworkSubnetConfig ` 362 | -Name $secondaryMiSubnetName ` 363 | -VirtualNetwork $SecondaryVirtualNetwork ` 364 | -AddressPrefix $secondaryMiSubnetAddress ` 365 | -Delegation $secondarySubnetDelegation ` 366 | | Set-AzVirtualNetwork 367 | $SecondaryVirtualNetwork 368 | Write-host "Secondary virtual network configured successfully." 369 | 370 | 371 | # Configure the secondary managed instance subnet 372 | Write-host "Configuring secondary MI subnet..." 373 | 374 | $SecondaryVirtualNetwork = Get-AzVirtualNetwork -Name $secondaryVNet ` 375 | -ResourceGroupName $resourceGroupName 376 | 377 | $secondaryMiSubnetConfig = Get-AzVirtualNetworkSubnetConfig ` 378 | -Name $secondaryMiSubnetName ` 379 | -VirtualNetwork $SecondaryVirtualNetwork 380 | $secondaryMiSubnetConfig 381 | Write-host "Secondary MI subnet configured successfully." 382 | 383 | 384 | # Configure the secondary network security group management service 385 | Write-host "Configuring secondary network security group management service..." 386 | 387 | $secondaryMiSubnetConfigId = $secondaryMiSubnetConfig.Id 388 | 389 | $secondaryNSGMiManagementService = New-AzNetworkSecurityGroup ` 390 | -Name 'secondaryToMIManagementService' ` 391 | -ResourceGroupName $resourceGroupName ` 392 | -location $drlocation 393 | $secondaryNSGMiManagementService 394 | Write-host "Secondary network security group management service configured successfully." 395 | 396 | 397 | # Configure the secondary route table MI management service 398 | Write-host "Configuring secondary route table MI management service..." 399 | 400 | $secondaryRouteTableMiManagementService = New-AzRouteTable ` 401 | -Name 'secondaryRouteTableMiManagementService' ` 402 | -ResourceGroupName $resourceGroupName ` 403 | -location $drlocation 404 | $secondaryRouteTableMiManagementService 405 | Write-host "Secondary route table MI management service configured successfully." 406 | 407 | 408 | # Configure the secondary network security group 409 | Write-host "Configuring secondary network security group..." 410 | 411 | Set-AzVirtualNetworkSubnetConfig ` 412 | -VirtualNetwork $SecondaryVirtualNetwork ` 413 | -Name $secondaryMiSubnetName ` 414 | -AddressPrefix $secondaryMiSubnetAddress ` 415 | -NetworkSecurityGroup $secondaryNSGMiManagementService ` 416 | -RouteTable $secondaryRouteTableMiManagementService ` 417 | -Delegation $secondarySubnetDelegation ` 418 | | Set-AzVirtualNetwork 419 | 420 | Get-AzNetworkSecurityGroup ` 421 | -ResourceGroupName $resourceGroupName ` 422 | -Name "secondaryToMIManagementService" ` 423 | | Add-AzNetworkSecurityRuleConfig ` 424 | -Priority 100 ` 425 | -Name "allow_management_inbound" ` 426 | -Access Allow ` 427 | -Protocol Tcp ` 428 | -Direction Inbound ` 429 | -SourcePortRange * ` 430 | -SourceAddressPrefix * ` 431 | -DestinationPortRange 9000,9003,1438,1440,1452 ` 432 | -DestinationAddressPrefix * ` 433 | | Add-AzNetworkSecurityRuleConfig ` 434 | -Priority 200 ` 435 | -Name "allow_misubnet_inbound" ` 436 | -Access Allow ` 437 | -Protocol * ` 438 | -Direction Inbound ` 439 | -SourcePortRange * ` 440 | -SourceAddressPrefix $secondaryMiSubnetAddress ` 441 | -DestinationPortRange * ` 442 | -DestinationAddressPrefix * ` 443 | | Add-AzNetworkSecurityRuleConfig ` 444 | -Priority 300 ` 445 | -Name "allow_health_probe_inbound" ` 446 | -Access Allow ` 447 | -Protocol * ` 448 | -Direction Inbound ` 449 | -SourcePortRange * ` 450 | -SourceAddressPrefix AzureLoadBalancer ` 451 | -DestinationPortRange * ` 452 | -DestinationAddressPrefix * ` 453 | | Add-AzNetworkSecurityRuleConfig ` 454 | -Priority 1000 ` 455 | -Name "allow_tds_inbound" ` 456 | -Access Allow ` 457 | -Protocol Tcp ` 458 | -Direction Inbound ` 459 | -SourcePortRange * ` 460 | -SourceAddressPrefix VirtualNetwork ` 461 | -DestinationPortRange 1433 ` 462 | -DestinationAddressPrefix * ` 463 | | Add-AzNetworkSecurityRuleConfig ` 464 | -Priority 1100 ` 465 | -Name "allow_redirect_inbound" ` 466 | -Access Allow ` 467 | -Protocol Tcp ` 468 | -Direction Inbound ` 469 | -SourcePortRange * ` 470 | -SourceAddressPrefix VirtualNetwork ` 471 | -DestinationPortRange 11000-11999 ` 472 | -DestinationAddressPrefix * ` 473 | | Add-AzNetworkSecurityRuleConfig ` 474 | -Priority 1200 ` 475 | -Name "allow_geodr_inbound" ` 476 | -Access Allow ` 477 | -Protocol Tcp ` 478 | -Direction Inbound ` 479 | -SourcePortRange * ` 480 | -SourceAddressPrefix VirtualNetwork ` 481 | -DestinationPortRange 5022 ` 482 | -DestinationAddressPrefix * ` 483 | | Add-AzNetworkSecurityRuleConfig ` 484 | -Priority 4096 ` 485 | -Name "deny_all_inbound" ` 486 | -Access Deny ` 487 | -Protocol * ` 488 | -Direction Inbound ` 489 | -SourcePortRange * ` 490 | -SourceAddressPrefix * ` 491 | -DestinationPortRange * ` 492 | -DestinationAddressPrefix * ` 493 | | Add-AzNetworkSecurityRuleConfig ` 494 | -Priority 100 ` 495 | -Name "allow_management_outbound" ` 496 | -Access Allow ` 497 | -Protocol Tcp ` 498 | -Direction Outbound ` 499 | -SourcePortRange * ` 500 | -SourceAddressPrefix * ` 501 | -DestinationPortRange 80,443,12000 ` 502 | -DestinationAddressPrefix * ` 503 | | Add-AzNetworkSecurityRuleConfig ` 504 | -Priority 200 ` 505 | -Name "allow_misubnet_outbound" ` 506 | -Access Allow ` 507 | -Protocol * ` 508 | -Direction Outbound ` 509 | -SourcePortRange * ` 510 | -SourceAddressPrefix * ` 511 | -DestinationPortRange * ` 512 | -DestinationAddressPrefix $secondaryMiSubnetAddress ` 513 | | Add-AzNetworkSecurityRuleConfig ` 514 | -Priority 1100 ` 515 | -Name "allow_redirect_outbound" ` 516 | -Access Allow ` 517 | -Protocol Tcp ` 518 | -Direction Outbound ` 519 | -SourcePortRange * ` 520 | -SourceAddressPrefix VirtualNetwork ` 521 | -DestinationPortRange 11000-11999 ` 522 | -DestinationAddressPrefix * ` 523 | | Add-AzNetworkSecurityRuleConfig ` 524 | -Priority 1200 ` 525 | -Name "allow_geodr_outbound" ` 526 | -Access Allow ` 527 | -Protocol Tcp ` 528 | -Direction Outbound ` 529 | -SourcePortRange * ` 530 | -SourceAddressPrefix VirtualNetwork ` 531 | -DestinationPortRange 5022 ` 532 | -DestinationAddressPrefix * ` 533 | | Add-AzNetworkSecurityRuleConfig ` 534 | -Priority 4096 ` 535 | -Name "deny_all_outbound" ` 536 | -Access Deny ` 537 | -Protocol * ` 538 | -Direction Outbound ` 539 | -SourcePortRange * ` 540 | -SourceAddressPrefix * ` 541 | -DestinationPortRange * ` 542 | -DestinationAddressPrefix * ` 543 | | Set-AzNetworkSecurityGroup 544 | Write-host "Secondary network security group configured successfully." 545 | 546 | # Configure the secondary network route table 547 | Write-host "Configuring secondary network route table..." 548 | Get-AzRouteTable ` 549 | -ResourceGroupName $resourceGroupName ` 550 | -Name "secondaryRouteTableMiManagementService" ` 551 | | Add-AzRouteConfig ` 552 | -Name "secondaryToMIManagementService" ` 553 | -AddressPrefix 0.0.0.0/0 ` 554 | -NextHopType Internet ` 555 | | Add-AzRouteConfig ` 556 | -Name "ToLocalClusterNode" ` 557 | -AddressPrefix $secondaryMiSubnetAddress ` 558 | -NextHopType VnetLocal ` 559 | | Set-AzRouteTable 560 | Write-host "Secondary network route table configured successfully." 561 | 562 | 563 | # Create the secondary managed instance 564 | $primaryManagedInstanceId = Get-AzSqlInstance -Name $primaryInstance -ResourceGroupName $resourceGroupName | Select-Object Id 565 | 566 | 567 | Write-host "Creating secondary SQL Managed Instance..." 568 | Write-host "This will take some time, see https://learn.microsoft.com/azure/azure-sql/managed-instance/management-operations-overview for more information." 569 | New-AzSqlInstance -Name $secondaryInstance ` 570 | -ResourceGroupName $resourceGroupName ` 571 | -Location $drLocation ` 572 | -SubnetId $secondaryMiSubnetConfigId ` 573 | -AdministratorCredential $mycreds ` 574 | -StorageSizeInGB $maxStorage ` 575 | -VCore $vCores ` 576 | -Edition $edition ` 577 | -ComputeGeneration $computeGeneration ` 578 | -LicenseType $license ` 579 | -DnsZonePartner $primaryManagedInstanceId.Id 580 | Write-host "Secondary SQL Managed Instance created successfully." 581 | 582 | # 583 | 584 | <#=========================================================================== 585 | The following configures the failover group 586 | ===========================================================================#> 587 | 588 | # 589 | 590 | # Create global virtual network peering 591 | $primaryVirtualNetwork = Get-AzVirtualNetwork ` 592 | -Name $primaryVNet ` 593 | -ResourceGroupName $resourceGroupName 594 | 595 | $secondaryVirtualNetwork = Get-AzVirtualNetwork ` 596 | -Name $secondaryVNet ` 597 | -ResourceGroupName $resourceGroupName 598 | 599 | Write-host "Peering primary VNet to secondary VNet..." 600 | Add-AzVirtualNetworkPeering ` 601 | -Name primaryVnet-secondaryVNet1 ` 602 | -VirtualNetwork $primaryVirtualNetwork ` 603 | -RemoteVirtualNetworkId $secondaryVirtualNetwork.Id 604 | Write-host "Primary VNet peered to secondary VNet successfully." 605 | 606 | Write-host "Peering secondary VNet to primary VNet..." 607 | Add-AzVirtualNetworkPeering ` 608 | -Name secondaryVNet-primaryVNet ` 609 | -VirtualNetwork $secondaryVirtualNetwork ` 610 | -RemoteVirtualNetworkId $primaryVirtualNetwork.Id 611 | Write-host "Secondary VNet peered to primary VNet successfully." 612 | 613 | Write-host "Checking peering state on the primary virtual network..." 614 | Get-AzVirtualNetworkPeering ` 615 | -ResourceGroupName $resourceGroupName ` 616 | -VirtualNetworkName $primaryVNet ` 617 | | Select PeeringState 618 | 619 | Write-host "Checking peering state on the secondary virtual network..." 620 | Get-AzVirtualNetworkPeering ` 621 | -ResourceGroupName $resourceGroupName ` 622 | -VirtualNetworkName $secondaryVNet ` 623 | | Select PeeringState 624 | 625 | # 626 | 627 | # 628 | 629 | # Create failover group 630 | Write-host "Creating the failover group..." 631 | $failoverGroup = New-AzSqlDatabaseInstanceFailoverGroup -Name $failoverGroupName ` 632 | -Location $location -ResourceGroupName $resourceGroupName -PrimaryManagedInstanceName $primaryInstance ` 633 | -PartnerRegion $drLocation -PartnerManagedInstanceName $secondaryInstance ` 634 | -FailoverPolicy Manual -GracePeriodWithDataLossHours 1 635 | $failoverGroup 636 | 637 | # 638 | 639 | 640 | # 641 | 642 | # Verify the current primary role 643 | Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName ` 644 | -Location $location -Name $failoverGroupName 645 | 646 | # 647 | 648 | # 649 | # Failover the primary managed instance to the secondary role 650 | Write-host "Failing primary over to the secondary location" 651 | Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName ` 652 | -Location $drLocation -Name $failoverGroupName | Switch-AzSqlDatabaseInstanceFailoverGroup 653 | Write-host "Successfully failed failover group to secondary location" 654 | 655 | # Verify the current primary role 656 | Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName ` 657 | -Location $drLocation -Name $failoverGroupName 658 | 659 | # 660 | 661 | # 662 | 663 | # Fail primary managed instance back to primary role 664 | Write-host "Failing primary back to primary role" 665 | Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName ` 666 | -Location $location -Name $failoverGroupName | Switch-AzSqlDatabaseInstanceFailoverGroup 667 | Write-host "Successfully failed failover group to primary location" 668 | 669 | # Verify the current primary role 670 | Get-AzSqlDatabaseInstanceFailoverGroup -ResourceGroupName $resourceGroupName ` 671 | -Location $location -Name $failoverGroupName 672 | 673 | # 674 | 675 | # Clean up deployment  676 | <# You will need to remove the resource group twice. Removing the resource group the first time will remove the managed instance and virtual clusters but will then fail with the error message `Remove-AzResourceGroup : Long running operation failed with status 'Conflict'.`. Run the Remove-AzResourceGroup command a second time to remove any residual resources as well as the resource group. #> 677 | 678 | # Remove-AzResourceGroup -ResourceGroupName $resourceGroupName 679 | # Write-host "Removing managed instance and virtual cluster..." 680 | # Remove-AzResourceGroup -ResourceGroupName $resourceGroupName 681 | # Write-host "Removing residual resources and resource group..." 682 | 683 | 684 | # Show randomized variables 685 | Write-host "Resource group name is" $resourceGroupName 686 | Write-host "Password is" $secpasswd 687 | Write-host "Primary Virtual Network name is" $primaryVNet 688 | Write-host "Primary default subnet name is" $primaryDefaultSubnet 689 | Write-host "Primary managed instance subnet name is" $primaryMiSubnetName 690 | Write-host "Secondary Virtual Network name is" $secondaryVNet 691 | Write-host "Secondary default subnet name is" $secondaryDefaultSubnet 692 | Write-host "Secondary managed instance subnet name is" $secondaryMiSubnetName 693 | Write-host "Primary managed instance name is" $primaryInstance 694 | Write-host "Secondary managed instance name is" $secondaryInstance 695 | Write-host "Failover group name is" $failoverGroupName 696 | 697 | # 698 | -------------------------------------------------------------------------------- /azure-sql/virtual-machine/create-sql-server-vm.ps1: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # 4 | $SubscriptionId = "" 5 | $Location = "" 6 | $ResourceGroupName = "" 7 | $userName = " 9 | 10 | # 11 | $StorageName = "sqlvm" + "storage" 12 | $StorageSku = "Premium_LRS" 13 | # 14 | 15 | # 16 | $InterfaceName = $ResourceGroupName + "ServerInterface" 17 | $NsgName = $ResourceGroupName + "nsg" 18 | $TCPIPAllocationMethod = "Dynamic" 19 | $VNetName = $ResourceGroupName + "VNet" 20 | $SubnetName = "Default" 21 | $VNetAddressPrefix = "10.0.0.0/16" 22 | $VNetSubnetAddressPrefix = "10.0.0.0/24" 23 | $DomainName = $ResourceGroupName 24 | # 25 | 26 | # 27 | $VMName = $ResourceGroupName + "VM" 28 | $ComputerName = $ResourceGroupName + "Server" 29 | $VMSize = "Standard_DS13" 30 | $OSDiskName = $VMName + "OSDisk" 31 | # 32 | 33 | # 34 | $OfferName = "SQL2022-WS2022" 35 | $PublisherName = "MicrosoftSQLServer" 36 | $Version = "latest" 37 | $Sku = "SQLDEV-GEN2" 38 | $License = 'PAYG' 39 | 40 | # 41 | # Define a credential object 42 | $SecurePassword = ConvertTo-SecureString '' ` 43 | -AsPlainText -Force 44 | $Cred = New-Object System.Management.Automation.PSCredential ($userName, $securePassword) 45 | # 46 | # 47 | 48 | # 49 | 50 | # 51 | 52 | # 53 | 54 | # Set subscription context 55 | Connect-AzAccount 56 | $subscriptionContextParams = @{ 57 | SubscriptionId = $SubscriptionId 58 | } 59 | Set-AzContext @subscriptionContextParams 60 | 61 | # Create a resource group 62 | $resourceGroupParams = @{ 63 | Name = $resourceGroupName 64 | Location = $Location 65 | Tag = @{Owner="SQLDocs-Samples"} 66 | } 67 | $resourceGroup = New-AzResourceGroup @resourceGroupParams 68 | 69 | # 70 | 71 | 72 | # 73 | # Create storage account 74 | $StorageAccount = New-AzStorageAccount -ResourceGroupName $ResourceGroupName ` 75 | -Name $StorageName -SkuName $StorageSku ` 76 | -Kind "Storage" -Location $Location 77 | # 78 | 79 | # 80 | # Create a subnet configuration 81 | $SubnetConfig = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $VNetSubnetAddressPrefix 82 | # 83 | 84 | # 85 | # Create a virtual network 86 | $VNet = New-AzVirtualNetwork -Name $VNetName ` 87 | -ResourceGroupName $ResourceGroupName -Location $Location ` 88 | -AddressPrefix $VNetAddressPrefix -Subnet $SubnetConfig 89 | # 90 | 91 | # 92 | # Create a public IP address 93 | $PublicIp = New-AzPublicIpAddress -Name $InterfaceName ` 94 | -ResourceGroupName $ResourceGroupName -Location $Location ` 95 | -AllocationMethod $TCPIPAllocationMethod -DomainNameLabel $DomainName 96 | # 97 | 98 | # 99 | # Create a network security group rule 100 | $NsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name "RDPRule" -Protocol Tcp ` 101 | -Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * ` 102 | -DestinationAddressPrefix * -DestinationPortRange 3389 -Access Allow 103 | 104 | $NsgRuleSQL = New-AzNetworkSecurityRuleConfig -Name "MSSQLRule" -Protocol Tcp ` 105 | -Direction Inbound -Priority 1001 -SourceAddressPrefix * -SourcePortRange * ` 106 | -DestinationAddressPrefix * -DestinationPortRange 1433 -Access Allow 107 | # 108 | 109 | # 110 | # Create a network security group 111 | $Nsg = New-AzNetworkSecurityGroup -ResourceGroupName $ResourceGroupName ` 112 | -Location $Location -Name $NsgName ` 113 | -SecurityRules $NsgRuleRDP,$NsgRuleSQL 114 | # 115 | 116 | # 117 | # Create a network interface 118 | $Interface = New-AzNetworkInterface -Name $InterfaceName ` 119 | -ResourceGroupName $ResourceGroupName -Location $Location ` 120 | -SubnetId $VNet.Subnets[0].Id -PublicIpAddressId $PublicIp.Id ` 121 | -NetworkSecurityGroupId $Nsg.Id 122 | # 123 | 124 | # 125 | # Create a virtual machine configuration 126 | $VMName = $ResourceGroupName + "VM" 127 | $VMConfig = New-AzVMConfig -VMName $VMName -VMSize $VMSize | 128 | Set-AzVMOperatingSystem -Windows -ComputerName $VMName -Credential $Cred -ProvisionVMAgent -EnableAutoUpdate | 129 | Set-AzVMSourceImage -PublisherName $PublisherName -Offer $OfferName -Skus $Sku -Version $Version | 130 | Add-AzVMNetworkInterface -Id $Interface.Id 131 | 132 | # Create the VM 133 | New-AzVM -ResourceGroupName $ResourceGroupName -Location $Location -VM $VMConfig 134 | # 135 | 136 | # 137 | 138 | # Register the SQL IaaS Agent extension to your subscription 139 | Register-AzResourceProvider -ProviderNamespace Microsoft.SqlVirtualMachine 140 | 141 | # Register SQL Server VM with the extension 142 | New-AzSqlVM -Name $VMName -ResourceGroupName $ResourceGroupName -Location $Location ` 143 | -LicenseType $License 144 | # 145 | 146 | # 147 | 148 | # 149 | # Clean up deployment  150 | # Stop-AzVM -Name $VMName -ResourceGroupName $ResourceGroupName 151 | # Remove-AzResourceGroup -ResourceGroupName $ResourceGroupName 152 | # 153 | -------------------------------------------------------------------------------- /container-registry/README.md: -------------------------------------------------------------------------------- 1 | # Azure Container Registry 2 | 3 | ## PowerShell sample scripts 4 | 5 | The scripts in this directory demonstrate working with [Azure Container Registry][acr-home] using the [Azure PowerShell][azure-psh] cmdlets. 6 | 7 | | Script | Description | 8 | | ------ | ----------- | 9 | |[service-principal-assign-role.ps1][sp-assign]| Assigns a role to an existing Azure Active Directory service principal, granting the service principal access to an Azure Container Registry. | 10 | |[service-principal-create.ps1][sp-create]| Creates a new Azure Active Directory service principal with permissions to an Azure Container Registry. | 11 | 12 | 13 | [sp-assign]: ./service-principal-assign-role/service-principal-assign-role.ps1 14 | [sp-create]: ./service-principal-create/service-principal-create.ps1 15 | 16 | 17 | [acr-home]: https://azure.microsoft.com/services/container-registry/ 18 | [azure-psh]: https://docs.microsoft.com/powershell/azure/overview -------------------------------------------------------------------------------- /container-registry/service-principal-assign-role/service-principal-assign-role.ps1: -------------------------------------------------------------------------------- 1 | # Modify for your environment. The 'registryName' is the name of your Azure 2 | # Container Registry, the 'resourceGroup' is the name of the resource group 3 | # in which your registry resides, and the 'servicePrincipalId' is the 4 | # service principal's 'ApplicationId' or one of its 'servicePrincipalNames'. 5 | $registryName = "" 6 | $resourceGroup = "" 7 | $servicePrincipalId = "" 8 | 9 | # Get a reference to the container registry; need its fully qualified ID 10 | # when assigning the role to the principal in a subsequent command. 11 | $registry = Get-AzContainerRegistry -ResourceGroupName $resourceGroup -Name $registryName 12 | 13 | # Get the existing service principal; need its 'ObjectId' value 14 | # when assigning the role to the principal in a subsequent command. 15 | $sp = Get-AzADServicePrincipal -ServicePrincipalName $servicePrincipalId 16 | 17 | # Assign the role to the service principal, identified using 'ObjectId'. Default permissions are for docker 18 | # pull access. Modify the 'RoleDefinitionName' argument value as desired: 19 | # acrpull: pull only 20 | # acrpush: push and pull 21 | # Owner: push, pull, and assign roles 22 | $role = New-AzRoleAssignment -ObjectId $sp.Id -RoleDefinitionName acrpull -Scope $registry.Id 23 | -------------------------------------------------------------------------------- /container-registry/service-principal-create/service-principal-create.ps1: -------------------------------------------------------------------------------- 1 | # This sample requires the Az PowerShell module version 7.x or higher. 2 | 3 | # Modify for your environment. The 'registryName' is the name of your Azure 4 | # Container Registry, the 'resourceGroup' is the name of the resource group 5 | # in which your registry resides, and the 'servicePrincipalName' can be any 6 | # unique name within your subscription (you can use the default below). 7 | $registryName = '' 8 | $resourceGroup = '' 9 | $servicePrincipalName = 'acr-service-principal' 10 | 11 | # Get a reference to the container registry; need its fully qualified ID 12 | # when assigning the role to the principal in a subsequent command. 13 | $registry = Get-AzContainerRegistry -ResourceGroupName $resourceGroup -Name $registryName 14 | 15 | # Create the service principal 16 | $sp = New-AzADServicePrincipal -DisplayName $servicePrincipalName 17 | 18 | # Sleep a few seconds to allow the service principal to propagate throughout 19 | # Azure Active Directory 20 | Start-Sleep -Seconds 30 21 | 22 | # Assign the role to the service principal. Default permissions are for docker 23 | # pull access. Modify the 'RoleDefinitionName' argument value as desired: 24 | # acrpull: pull only 25 | # acrpush: push and pull 26 | # Owner: push, pull, and assign roles 27 | New-AzRoleAssignment -ObjectId $sp.Id -RoleDefinitionName acrpull -Scope $registry.Id 28 | 29 | # Output the service principal's credentials; use these in your services and 30 | # applications to authenticate to the container registry. 31 | Write-Output "Service principal App ID: $($sp.AppId)" 32 | Write-Output "Service principal password: $($sp.PasswordCredentials.SecretText)" 33 | -------------------------------------------------------------------------------- /expressroute-gateway/gateway-migration/README.md: -------------------------------------------------------------------------------- 1 | # Run the following operations to migrate gateway 2 | 3 | 1. Enable AFEC flag on customer subscription: 4 | - AllowDeletionOfIpPrefixFromSubnet 5 | - AllowMultipleAddressPrefixesOnSubnet 6 | 1. Install the latest PowerShell for Az.Network Module to have the new API to enable/disable gateway 7 | 1. Run `PrepareMigration.ps1`, this script performs validation and create all new resources : 8 | gateway and connections 9 | 1. Run `Migration.ps1`. This script switches traffic from one gateway to another 10 | 1. Run `CommitMigration.ps1`. This script removes unused resources: disabled gateway and its 11 | connections 12 | 1. For rollback, run `Migration.ps1` to switch back to original gateway then run 13 | `CommitMigration.ps1` 14 | 1. Note: No resources other than ER gateway and connection should have any change during this 15 | migration flow 16 | 17 | ## Sample output 18 | 19 | ```Output 20 | Script to prepare migration and create resources 21 | C:\code\Networking-nfv\TSGs\ExpressRoute\TSGs\GatewayMigration> .\PrepareMigration.ps1 22 | Prepare Migration: Please Enter Gateway Resource ID: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 23 | Customer Subscription ID: 00000000-0000-0000-0000-000000000000 24 | Getting existing resources for gateway: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 25 | ---------------- All validation passed, start creating new resources ---------------- 26 | Please choose the suffix for new resources, new resource name will be existingresourcename_: new 27 | Please select zones for new gateway: 1 28 | Please choose the sku for new gateway [ErGw1AZ|ErGw2AZ|ErGw3AZ]: ErGw1AZ 29 | ---------------- Creating new gateway AzureGateway1_new Sku ErGw1AZ ---------------- 30 | ---------------- Creating new connection conn1_new with circuit /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/expressRouteCircuits/circuit ---------------- 31 | ---------------- Prepare for migration for /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 is completed! Taking 28.6089642616667 minutes ---------------- 32 | Enter anything to exit: 33 | 34 | Script to migrate traffic from old gateway to new gateway or vice verse 35 | PS C:\code\Networking-nfv\TSGs\ExpressRoute\TSGs\GatewayMigration> .\Migration.ps1 36 | Migrate from Gateway Resource ID: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 37 | Migrate to Gateway Resource ID: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1_new 38 | Customer Subscription ID: 00000000-0000-0000-0000-000000000000 39 | ---------------- Enabling gateway AzureGateway1_new ---------------- 40 | ---------------- Disabling gateway AzureGateway1 ---------------- 41 | ---------------- Migration from /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 to /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1_new is completed! Taking 4.87634857666667 minutes---------------- 42 | Enter anything to exit: 43 | 44 | Script to commit migration and delete resources 45 | PS C:\code\Networking-nfv\TSGs\ExpressRoute\TSGs\GatewayMigration> .\CommitMigration.ps1 46 | Commit Migration: Please Enter Gateway Resource ID: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 47 | Customer Subscription ID: 00000000-0000-0000-0000-000000000000 48 | ---------------- Found disabled gateway /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 ---------------- 49 | Please enter Y to confirm this is the gateway to be deleted /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1: y 50 | ---------------- Removing gateway AzureGateway1 ---------------- 51 | ---------------- Commit for migration for /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testtunnelciscop3/providers/Microsoft.Network/virtualNetworkGateways/AzureGateway1 is completed! Taking minutes---------------- 52 | Enter anything to exit: 53 | ``` 54 | -------------------------------------------------------------------------------- /expressroute-gateway/gateway-migration/commitmigration.ps1: -------------------------------------------------------------------------------- 1 | # Start preparing 2 | $gatewayUri = Read-Host "Commit Migration: Please Enter Gateway Resource ID" 3 | $subIdRegex = "subscriptions/" 4 | $resourceGroupRegex = "resourceGroups/" 5 | $vnetRegex = "virtualNetworks/" 6 | $gatewayRegex = "virtualNetworkGateways/" 7 | $ipconfigRegex = "ipConfigurations/" 8 | $subId = $gatewayUri.Substring($gatewayUri.ToLower().IndexOf($subIdRegex.ToLower()) + $subIdRegex.Length, $gatewayUri.ToLower().IndexOf($resourceGroupRegex.ToLower()) - $gatewayUri.ToLower().IndexOf($subIdRegex.ToLower()) - $subIdRegex.Length -1) 9 | Write-Host "Customer Subscription ID:" $subId 10 | Connect-AzAccount -WarningAction Ignore | Out-Null 11 | Select-AzSubscription -Subscription $subId -Force | Out-null 12 | $gateway = Get-AzResource -ResourceId $gatewayUri 13 | $resourceGroup = $gateway.ResourceGroupName 14 | $subnet = Get-AzResource -ResourceId $gateway.Properties.ipConfigurations[0].properties.subnet.id 15 | $vnetName = $subnet.ParentResource.Substring($subnet.ParentResource.ToLower().IndexOf($vnetRegex.ToLower()) + $vnetRegex.Length, $subnet.ParentResource.Length - $subnet.ParentResource.ToLower().IndexOf($vnetRegex.ToLower()) - $vnetRegex.Length) 16 | $vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $resourceGroup 17 | $subnet = Get-AzVirtualNetworkSubnetConfig -Name GatewaySubnet -VirtualNetwork $vnet 18 | $gatewayToDelete = "" 19 | foreach($ipconfig in $subnet.IpConfigurations) 20 | { 21 | $gatewayName = $ipconfig.Id.substring($ipconfig.Id.ToLower().IndexOf($gatewayRegex.ToLower()) + $gatewayRegex.Length, $ipconfig.Id.ToLower().IndexOf($ipconfigRegex.ToLower()) - $ipconfig.Id.ToLower().IndexOf($gatewayRegex.ToLower()) - $gatewayRegex.Length-1) 22 | $tempGwt = get-AzVirtualNetworkGateway -Name $gatewayName -ResourceGroupName $gateway.ResourceGroupName 23 | if($tempGwt.AdminState.tolower().Contains("disable")) 24 | { 25 | $gatewayToDelete = $tempGwt.Id 26 | } 27 | } 28 | 29 | Write-Host "---------------- Found disabled gateway" $gatewayToDelete "----------------" 30 | $confirm = Read-Host "Please enter Y to confirm this is the gateway to be deleted" $gatewayToDelete 31 | $confirm 32 | if($confirm.ToLower() -ne "y") 33 | { 34 | Read-Host "Enter anything to exit, Commit for migration is cancelled" 35 | exit 36 | } 37 | 38 | # Getting input from customer and delete resources 39 | $startTime = Get-Date 40 | $connections = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $gateway.ResourceGroupName | Where-Object -FilterScript {$_.VirtualNetworkGateway1.Id -eq $gatewayToDelete} 41 | foreach($connection in $connections) 42 | { 43 | if($connection.ProvisioningState -ne "Succeeded") 44 | { 45 | Write-Host $connection.Name " is " $connection.ProvisioningState 46 | Read-Host "Enter anything to exit, Prepare for migration failed" 47 | exit 48 | } 49 | } 50 | 51 | foreach($connection in $connections) 52 | { 53 | Write-Host "---------------- Removing connection" $connection.Name "----------------" 54 | Remove-AzVirtualNetworkGatewayConnection -Name $connection.Name -ResourceGroupName $connection.ResourceGroupName -Force 55 | } 56 | 57 | $gateway = Get-AzResource -ResourceId $gatewayToDelete 58 | Write-Host "---------------- Removing gateway" $gateway.Name "----------------" 59 | Remove-AzVirtualNetworkGateway -Name $gateway.Name -ResourceGroupName $gateway.ResourceGroupName -Force 60 | 61 | # Commit completed! 62 | $endTime = Get-Date 63 | $diff = New-TimeSpan -Start $startTime -End $endTime 64 | Write-Host "---------------- Commit for migration for" $gatewayToDelete "is completed! Taking" $diff.TotalMinutes "minutes----------------" 65 | Read-Host "Enter anything to exit" 66 | -------------------------------------------------------------------------------- /expressroute-gateway/gateway-migration/migration.ps1: -------------------------------------------------------------------------------- 1 | # Need to verify PS module to ensure have the new API for PUT Gateway 2 | 3 | 4 | # Start preparing 5 | $gatewayUriDisabled = Read-Host "Migrate from Gateway Resource ID" 6 | $gatewayUriEnabled = Read-Host "Migrate to Gateway Resource ID" 7 | $subIdRegex = "subscriptions/" 8 | $resourceGroupRegex = "resourceGroups/" 9 | $vnetRegex = "virtualNetworks/" 10 | $subId = $gatewayUriDisabled.Substring($gatewayUriDisabled.ToLower().IndexOf($subIdRegex.ToLower()) + $subIdRegex.Length, $gatewayUriDisabled.ToLower().IndexOf($resourceGroupRegex.ToLower()) - $gatewayUriDisabled.ToLower().IndexOf($subIdRegex.ToLower()) - $subIdRegex.Length -1) 11 | Write-Host "Customer Subscription ID:" $subId 12 | Connect-AzAccount -WarningAction Ignore | Out-Null 13 | Select-AzSubscription -Subscription $subId -Force | Out-null 14 | $gatewayDisabled = Get-AzResource -ResourceId $gatewayUriDisabled 15 | $gatewayEnabled = Get-AzResource -ResourceId $gatewayUriEnabled 16 | $gwtDisabled = Get-AzVirtualNetworkGateway -Name $gatewayDisabled.Name -ResourceGroupName $gatewayDisabled.ResourceGroupName 17 | $gwtEnabled = Get-AzVirtualNetworkGateway -Name $gatewayEnabled.Name -ResourceGroupName $gatewayEnabled.ResourceGroupName 18 | $resourceGroup = $gatewayDisabled.ResourceGroupName 19 | # Validate all connections and gateways 20 | if($gwtEnabled.provisioningState -ne "Succeeded") 21 | { 22 | Write-Host $gwtEnabled.Name " is " $gwtEnabled.provisioningState 23 | Read-Host "Enter anything to exit, Migration failed" 24 | exit 25 | } 26 | 27 | $connections = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $resourceGroup | Where-Object -FilterScript {$_.VirtualNetworkGateway1.Id -eq $gatewayUriEnabled} 28 | foreach($connection in $connections) 29 | { 30 | if($connection.ProvisioningState -ne "Succeeded") 31 | { 32 | Write-Host $connection.Name " is " $connection.ProvisioningState 33 | Read-Host "Enter anything to exit, Prepare for migration failed" 34 | exit 35 | } 36 | } 37 | 38 | if($gwtDisabled.provisioningState -ne "Succeeded") 39 | { 40 | Write-Host $gwtDisabled.Name " is " $gwtDisabled.provisioningState 41 | Read-Host "Enter anything to exit, Migration failed" 42 | exit 43 | } 44 | 45 | $connections = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $resourceGroup | Where-Object -FilterScript {$_.VirtualNetworkGateway1.Id -eq $gatewayUriDisabled} 46 | foreach($connection in $connections) 47 | { 48 | if($connection.ProvisioningState -ne "Succeeded") 49 | { 50 | Write-Host $connection.Name " is " $connection.ProvisioningState 51 | Read-Host "Enter anything to exit, Prepare for migration failed" 52 | exit 53 | } 54 | } 55 | 56 | # Migrating traffic 57 | $startTime = Get-Date 58 | 59 | Write-Host "---------------- Enabling gateway" $gwtEnabled.Name "----------------" 60 | $gwt1 = Set-AzVirtualNetworkGateway -VirtualNetworkGateway $gwtEnabled -AdminState Enabled 61 | 62 | if($gwt1.ProvisioningState -ne "Succeeded") 63 | { 64 | Write-Host "Not able to enable" $gwt1.Name 65 | Read-Host "Enter anything to exit, Migration failed" 66 | exit 67 | } 68 | 69 | Write-Host "---------------- Disabling gateway" $gwtDisabled.Name "----------------" 70 | $gwt2 = Set-AzVirtualNetworkGateway -VirtualNetworkGateway $gwtDisabled -AdminState Disabled 71 | 72 | if($gwt2.ProvisioningState -ne "Succeeded") 73 | { 74 | Write-Host "Not able to disable" $gwt2.Name 75 | Read-Host "Enter anything to exit, Migration failed" 76 | exit 77 | } 78 | $endTime = Get-Date 79 | $diff = New-TimeSpan -Start $startTime -End $endTime 80 | # Migration completed! 81 | Write-Host "---------------- Migration from" $gatewayUriDisabled "to" $gatewayUriEnabled "is completed! Taking" $diff.TotalMinutes "minutes----------------" 82 | Read-Host "Enter anything to exit" -------------------------------------------------------------------------------- /expressroute-gateway/gateway-migration/preparemigration.ps1: -------------------------------------------------------------------------------- 1 | # Need to verify PS module to ensure have the new API for PUT Gateway 2 | # Start preparing 3 | $gatewayUri = Read-Host "Prepare Migration: Please Enter Gateway Resource ID" 4 | $subIdRegex = "subscriptions/" 5 | $resourceGroupRegex = "resourceGroups/" 6 | $vnetRegex = "virtualNetworks/" 7 | $subId = $gatewayUri.Substring($gatewayUri.ToLower().IndexOf($subIdRegex.ToLower()) + $subIdRegex.Length, $gatewayUri.ToLower().IndexOf($resourceGroupRegex.ToLower()) - $gatewayUri.ToLower().IndexOf($subIdRegex.ToLower()) - $subIdRegex.Length -1) 8 | Write-Host "Customer Subscription ID:" $subId 9 | Connect-AzAccount -WarningAction Ignore | Out-Null 10 | Select-AzSubscription -Subscription $subId -Force -WarningAction Ignore | Out-null 11 | Write-Host "Getting existing resources for gateway:" $gatewayUri 12 | $gateway = Get-AzResource -ResourceId $gatewayUri -WarningAction Ignore 13 | $resourceGroup = $gateway.ResourceGroupName 14 | $location = $gateway.Location 15 | $pip = Get-AzResource -ResourceId $gateway.Properties.ipConfigurations[0].properties.publicIPAddress.id 16 | $subnet = Get-AzResource -ResourceId $gateway.Properties.ipConfigurations[0].properties.subnet.id 17 | $vnetName = $subnet.ParentResource.Substring($subnet.ParentResource.ToLower().IndexOf($vnetRegex.ToLower()) + $vnetRegex.Length, $subnet.ParentResource.Length - $subnet.ParentResource.ToLower().IndexOf($vnetRegex.ToLower()) - $vnetRegex.Length) 18 | $vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $resourceGroup 19 | $subnet = Get-AzVirtualNetworkSubnetConfig -Name GatewaySubnet -VirtualNetwork $vnet 20 | # Verify all resources are in succeeded state 21 | if($gateway.Properties.provisioningState -ne "Succeeded") 22 | { 23 | Write-Host $gateway.Name " is " $gateway.Properties.provisioningState 24 | Read-Host "Enter anything to exit, Prepare for migration failed" 25 | exit 26 | } 27 | $connections = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $resourceGroup | Where-Object -FilterScript { 28 | $_.VirtualNetworkGateway1.Id -eq $gatewayUri 29 | } 30 | foreach($connection in $connections) 31 | { 32 | if($connection.ProvisioningState -ne "Succeeded") 33 | { 34 | Write-Host $connection.Name " is " $connection.ProvisioningState 35 | Read-Host "Enter anything to exit, Prepare for migration failed" 36 | exit 37 | } 38 | } 39 | Write-Host "---------------- All validation passed, start creating new resources ----------------" 40 | # Getting input from customer and create new resources 41 | $prefix = Read-Host "Please choose the suffix for new resources, new resource name will be existingresourcename_" 42 | $pipName = $pip.Name + "_" + $prefix 43 | $ipconfigName = $gateway.Properties.ipConfigurations[0].name + "_" + $prefix 44 | $gatewayName = $gateway.Name + "_" + $prefix 45 | $zone = Read-Host "Please select zones for new gateway, if region do not have zones, please select null" 46 | $gatewaySku = Read-Host "Please choose the sku for new gateway [ErGw1AZ|ErGw2AZ|ErGw3AZ], if region do not have zones [Standard|HighPerformance|UltraPerformance]" 47 | if($pipName.Length -gt 80) 48 | { 49 | $pipName = $pipName.Substring(0,80) 50 | } 51 | if($ipconfigName.Length -gt 80) 52 | { 53 | $ipconfigName = $ipconfigName.Substring(0,80) 54 | } 55 | if($gatewayName.Length -gt 80) 56 | { 57 | $gatewayName = $gatewayName.Substring(0,80) 58 | } 59 | if($zone -eq "null") 60 | { 61 | Write-Host "Region do not support zones" 62 | $zone = $null 63 | } 64 | $pipNew = New-AzPublicIpAddress -Name $pipName -ResourceGroupName $resourceGroup -Location $location -AllocationMethod Static -Sku Standard -Zone $zone -Force 65 | $subnetNew = Get-AzVirtualNetworkSubnetConfig -Name GatewaySubnet -VirtualNetwork $vnet 66 | $ipconfNew = New-AzVirtualNetworkGatewayIpConfig -Name $ipconfigName -Subnet $subnetNew -PublicIpAddress $pipNew 67 | $startTime = Get-Date 68 | Write-Host "---------------- Creating new gateway" $gatewayName "Sku" $gatewaySku "----------------" 69 | New-AzVirtualNetworkGateway -Name $gatewayName -ResourceGroupName $resourceGroup -Location $location -IpConfigurations $ipconfNew -GatewayType Expressroute -GatewaySku $gatewaysku -AdminState Disabled -Force | Out-null 70 | $gatewayNew = get-AzVirtualNetworkGateway -Name $gatewayName -ResourceGroupName $resourceGroup 71 | Set-AzVirtualNetworkGateway -VirtualNetworkGateway $gatewayNew -AllowRemoteVnetTraffic $gateway.AllowRemoteVnetTraffic -AllowVirtualWanTraffic $gateway.AllowVirtualWanTraffic 72 | $gatewayNew = get-AzVirtualNetworkGateway -Name $gatewayName -ResourceGroupName $resourceGroup 73 | if($gatewayNew.ProvisioningState -ne "Succeeded") 74 | { 75 | Write-Host $gatewayNew.Name " is " $gateway.ProvisioningState 76 | Read-Host "Enter anything to exit, Prepare for migration failed" 77 | exit 78 | } 79 | Set-AzVirtualNetworkGateway -VirtualNetworkGateway $gatewayNew -AllowRemoteVnetTraffic $true -AllowVirtualWanTraffic $true 80 | $gatewayNew = get-AzVirtualNetworkGateway -Name $gatewayName -ResourceGroupName $resourceGroup 81 | Write-Host New gateway properties: AllowRemoteVnetTraffic $gatewayNew.AllowRemoteVnetTraffic, AllowVirtualWanTraffic $gatewayNew.AllowVirtualWanTraffic 82 | foreach($connection in $connections) 83 | { 84 | $connName = $connection.Name + "_" + $prefix 85 | $circuitId = $connection.Peer.Id 86 | $isAuth = $true; 87 | $isFP = $true; 88 | $isFPPE = $true; 89 | if($connection.AuthorizationKey -eq $null -or $connection.AuthorizationKey -eq "") 90 | { 91 | $isAuth = $false 92 | } 93 | 94 | if($connection.ExpressRouteGatewayBypass -eq $null) 95 | { 96 | $isFP = $false 97 | } 98 | else 99 | { 100 | $isFP = $connection.ExpressRouteGatewayBypass 101 | } 102 | 103 | if($connection.EnablePrivateLinkFastPath -eq $null) 104 | { 105 | $isFPPE = $false 106 | } 107 | else 108 | { 109 | $isFPPE = $connection.EnablePrivateLinkFastPath 110 | } 111 | Write-Host Existing connection properties: ExpressRouteGatewayBypass: $connection.ExpressRouteGatewayBypass, EnablePrivateLinkFastPath: $connection.EnablePrivateLinkFastPath, Route Weight: $connection.RoutingWeight, AuthorizationKey: $connection.AuthorizationKey 112 | Write-Host Copying properties: ExpressRouteGatewayBypass: $isFP, EnablePrivateLinkFastPath: $isFPPE, Route Weight: $connection.RoutingWeight, AuthorizationKey: $isAuth 113 | 114 | if($isAuth) 115 | { 116 | if($isFP -and $isFPPE) 117 | { 118 | New-AzVirtualNetworkGatewayConnection -Name $connName -ResourceGroupName $resourceGroup -Location $location -VirtualNetworkGateway1 $gatewayNew -PeerId $circuitId -ConnectionType ExpressRoute -RoutingWeight $connection.RoutingWeight -ExpressRouteGatewayBypass -EnablePrivateLinkFastPath -AuthorizationKey "*****************" | Out-null 119 | } 120 | elseif($isFP) 121 | { 122 | New-AzVirtualNetworkGatewayConnection -Name $connName -ResourceGroupName $resourceGroup -Location $location -VirtualNetworkGateway1 $gatewayNew -PeerId $circuitId -ConnectionType ExpressRoute -RoutingWeight $connection.RoutingWeight -ExpressRouteGatewayBypass -AuthorizationKey "*****************" | Out-null 123 | } 124 | else 125 | { 126 | New-AzVirtualNetworkGatewayConnection -Name $connName -ResourceGroupName $resourceGroup -Location $location -VirtualNetworkGateway1 $gatewayNew -PeerId $circuitId -ConnectionType ExpressRoute -RoutingWeight $connection.RoutingWeight -AuthorizationKey "*****************" | Out-null 127 | } 128 | } 129 | else { 130 | if($isFP -and $isFPPE) 131 | { 132 | New-AzVirtualNetworkGatewayConnection -Name $connName -ResourceGroupName $resourceGroup -Location $location -VirtualNetworkGateway1 $gatewayNew -PeerId $circuitId -ConnectionType ExpressRoute -RoutingWeight $connection.RoutingWeight -ExpressRouteGatewayBypass -EnablePrivateLinkFastPath | Out-null 133 | } 134 | elseif($isFP) 135 | { 136 | New-AzVirtualNetworkGatewayConnection -Name $connName -ResourceGroupName $resourceGroup -Location $location -VirtualNetworkGateway1 $gatewayNew -PeerId $circuitId -ConnectionType ExpressRoute -RoutingWeight $connection.RoutingWeight -ExpressRouteGatewayBypass | Out-null 137 | } 138 | else 139 | { 140 | New-AzVirtualNetworkGatewayConnection -Name $connName -ResourceGroupName $resourceGroup -Location $location -VirtualNetworkGateway1 $gatewayNew -PeerId $circuitId -ConnectionType ExpressRoute -RoutingWeight $connection.RoutingWeight | Out-null 141 | } 142 | } 143 | 144 | $connNew = Get-AzVirtualNetworkGatewayConnection -Name $connName -ResourceGroupName $resourceGroup 145 | Write-Host New connection properties: ExpressRouteGatewayBypass: $connNew.ExpressRouteGatewayBypass, EnablePrivateLinkFastPath: $connNew.EnablePrivateLinkFastPath, Route Weight: $connNew.RoutingWeight, AuthorizationKey: $connNew.AuthorizationKey 146 | } 147 | 148 | $connectionsNew = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $resourceGroup | Where-Object -FilterScript { 149 | $_.VirtualNetworkGateway1.Name -contains $prefix 150 | } 151 | 152 | foreach($connection in $connectionsNew) 153 | { 154 | if($connection.ProvisioningState -ne "Succeeded") 155 | { 156 | Write-Host $connection.Name " is " $connection.ProvisioningState 157 | Read-Host "Enter anything to exit, Prepare for migration failed" 158 | exit 159 | } 160 | } 161 | $endTime = Get-Date 162 | $diff = New-TimeSpan -Start $startTime -End $endTime 163 | # Preparetion completed! 164 | Write-Host "---------------- Prepare for migration for" $gatewayUri "is completed! Taking" $diff.TotalMinutes "minutes ----------------" 165 | Read-Host "Enter anything to exit" 166 | -------------------------------------------------------------------------------- /expressroute/highAvailabilitySetup/Get-AzExpressRouteResilientLocations.md: -------------------------------------------------------------------------------- 1 | # Get-AzExpressRouteResilientLocations.ps1 2 | ## Syntax 3 | ``` 4 | Get-AzExpressRouteResilientLocations 5 | -SubscriptionId 6 | [-RelativeLocation ] 7 | [-LocationType ] 8 | ``` 9 | 10 | ## Description 11 | The **Get-AzExpressRouteResilientLocations** cmdlet gets a list of peering locations available for provider and port circuits. If RelativeLocation is provided, the distance from the location provided is returned. 12 | 13 | ## Examples 14 | ### Example 1: get all peering locations 15 | ``` 16 | .\Get-AzExpressRouteResilientLocations.ps1 -SubscriptionId $SubscriptionId 17 | ``` 18 | ### Example 2: get peering locations sorted by distance from Silicon Valley peering location 19 | ``` 20 | .\Get-AzExpressRouteResilientLocations.ps1 -SubscriptionId $SubscriptionId -RelativeLocation "silicon valley" 21 | ``` -------------------------------------------------------------------------------- /expressroute/highAvailabilitySetup/Get-AzExpressRouteResilientLocations.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory = $true)] 3 | [string]$SubscriptionId, 4 | 5 | [Parameter(Mandatory = $false)] 6 | [string]$RelativeLocation = "", 7 | 8 | [Parameter(Mandatory = $false)] 9 | [string]$LocationType = "" 10 | ) 11 | 12 | function UpdatePeeringLocationType { 13 | param ( 14 | [PSCustomObject]$location 15 | ) 16 | if ($location.properties.expressRouteLocationType -eq "ExpressRoutePortsLocation" -and $location.Name.ToLower().Contains("metro")) { 17 | $location.properties.expressRouteLocationType = "MetroDirectLocation" 18 | } 19 | elseif ($location.properties.expressRouteLocationType -eq "ExpressRoutePortsLocation" -and -not $location.Name.ToLower().Contains("metro")) { 20 | $location.properties.expressRouteLocationType = "ExpressRouteDirectLocation" 21 | } 22 | elseif ($location.properties.expressRouteLocationType -eq "ExpressRouteServiceProvidersLocation" -and $location.Name.ToLower().Contains("metro")) { 23 | $location.properties.expressRouteLocationType = "MetroPeeringLocation" 24 | } 25 | elseif ($location.properties.expressRouteLocationType -eq "ExpressRouteServiceProvidersLocation" -and -not $location.Name.ToLower().Contains("metro")) { 26 | $location.properties.expressRouteLocationType = "ExpressRoutePeeringLocation" 27 | } 28 | 29 | return $location 30 | } 31 | 32 | function Get-AzHighAvailabilityLocation { 33 | param ( 34 | [string]$SubscriptionId, 35 | [string]$RelativeLocation, 36 | [string]$LocationType 37 | ) 38 | 39 | $uri = "https://management.azure.com/subscriptions/$SubscriptionId/providers/Microsoft.Network/ExpressRoutePortsLocations?api-version=2023-09-01&includeAllLocations=true" 40 | if ($RelativeLocation -ne "") { 41 | $uri += "&relativeLocation=$RelativeLocation" 42 | } 43 | 44 | try { 45 | $token = (Get-AzAccessToken -WarningAction:SilentlyContinue).token 46 | $headers = @{ 'Authorization' = "Bearer $Token" } 47 | $locations = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers 48 | $locationMap = @() 49 | $providers = Get-AzExpressRouteServiceProvider -WarningAction:SilentlyContinue 50 | 51 | if ($RelativeLocation -ne "") { 52 | foreach ($location in $locations.value) { 53 | $location = UpdatePeeringLocationType -location $location 54 | 55 | if ($LocationType -eq "" -or $location.properties.expressRouteLocationType -eq $LocationType) 56 | { 57 | $providersAvailableAtThisPeeringLocation = @() 58 | if ($location.properties.relativeDistanceOfPeeringLocations -ne $null -and [double]$location.properties.relativeDistanceOfPeeringLocations -gt 0) { 59 | if ($location.properties.expressRouteLocationType.Contains("PeeringLocation")) { 60 | foreach ($provider in $providers) { 61 | if ($provider.PeeringLocations -icontains $location.Name) { 62 | $providersAvailableAtThisPeeringLocation += $provider.Name 63 | } 64 | } 65 | } 66 | 67 | $locationMap += [PSCustomObject]@{ 68 | Name = $location.name 69 | DistanceInKm = ([double]$location.properties.relativeDistanceOfPeeringLocations).ToString("N0") 70 | DistanceInMi = ([double]$location.properties.relativeDistanceOfPeeringLocations / 1.6).ToString("N0") 71 | Type = $location.properties.expressRouteLocationType 72 | ProvidersAvailableAtThisPeeringLocation = $providersAvailableAtThisPeeringLocation 73 | } 74 | } 75 | } 76 | } 77 | 78 | if ($locations.value.Count -gt 0 -and $locationMap.Count -eq 0) { 79 | Write-Error "Failed to get distances from peering location $RelativeLocation, please check spelling of peering location." 80 | return $null 81 | } 82 | } 83 | else { 84 | foreach ($location in $locations.value) { 85 | $location = UpdatePeeringLocationType -location $location 86 | $providersAvailableAtThisPeeringLocation = @() 87 | 88 | if ($LocationType -eq "" -or $location.properties.expressRouteLocationType -eq $LocationType) 89 | { 90 | if ($location.properties.expressRouteLocationType.Contains("PeeringLocation")) { 91 | foreach ($provider in $providers) { 92 | if ($provider.PeeringLocations -icontains $location.Name) { 93 | $providersAvailableAtThisPeeringLocation += $provider.Name 94 | } 95 | } 96 | } 97 | 98 | $locationMap += [PSCustomObject]@{ 99 | Name = $location.name 100 | Type = $location.properties.expressRouteLocationType 101 | ProvidersAvailableAtThisPeeringLocation = $providersAvailableAtThisPeeringLocation 102 | } 103 | } 104 | } 105 | } 106 | 107 | return $locationMap 108 | } catch { 109 | Write-Error "Failed to retrieve data from Azure API. $_" 110 | return $null 111 | } 112 | } 113 | 114 | $result = Get-AzHighAvailabilityLocation -SubscriptionId $SubscriptionId -RelativeLocation $RelativeLocation -LocationType $LocationType 115 | if ($result -ne $null) { 116 | $result | Format-Table -AutoSize | Out-Host -Paging 117 | } else { 118 | Write-Host "Failed to retrieve high availability locations." 119 | } 120 | -------------------------------------------------------------------------------- /expressroute/highAvailabilitySetup/New-AzHighAvailabilityExpressRouteCircuits.md: -------------------------------------------------------------------------------- 1 | # New-AzHighAvailabilityExpressRouteCircuits.ps1 2 | ## Syntax 3 | ``` 4 | New-AzHighAvailabilityExpressRouteCircuits 5 | -SubscriptionId 6 | -ResourceGroupName 7 | -Location 8 | [-Name1 ] 9 | -Name2 10 | [-SkuTier1 ] 11 | -SkuTier2 12 | [-SkuFamily1 ] 13 | -SkuFamily2 14 | [-ServiceProviderName ] 15 | [-ServiceProviderName ] 16 | [-PeeringLocation1 ] 17 | [-PeeringLocation2 ] 18 | -BandwidthInMbps 19 | [-ExpressRoutePort ] 20 | [-ExpressRoutePort ] 21 | [-ExistingCircuit] 22 | ``` 23 | 24 | ## Description 25 | The **New-AzHighAvailabilityExpressRouteCircuits** cmdlet creates a pair of Azure express route circuit. 26 | 27 | ## Examples 28 | ### Example 1: Create 2 new circuits, both on provider 29 | ``` 30 | .\New-AzHighAvailabilityExpressRouteCircuits.ps1 -SubscriptionId $SubscriptionId -ResourceGroupName $resourceGroupName -Location "westus" -Name1 $circuit1Name -Name2 $circuit2Name -SkuFamily1 "MeteredData" -SkuFamily2 "MeteredData" -SkuTier1 "Standard" -SkuTier2 "Standard" -ServiceProviderName1 "Equinix" -ServiceProviderName2 "Equinix" -PeeringLocation1 "Silicon Valley" -PeeringLocation2 "Washington DC" -BandwidthInMbps 1000 31 | ``` 32 | ### Example 2: Create 2 new circuits, both on port 33 | ``` 34 | $portResource1 = Get-AzExpressRoutePort -ResourceGroupName $resourceGroupName -Name $portName 35 | 36 | $portResource2 = Get-AzExpressRoutePort -ResourceGroupName $resourceGroupName -Name $port2Name 37 | 38 | .\New-AzHighAvailabilityExpressRouteCircuits.ps1 -SubscriptionId $SubscriptionId -ResourceGroupName $resourceGroupName -Location "westus" -Name1 $circuit1Name -Name2 $circuit2Name -SkuFamily1 "MeteredData" -SkuFamily2 "MeteredData" -SkuTier1 "Standard" -SkuTier2 "Standard" -BandwidthInMbps 5000 -ExpressRoutePort1 $portResource1 -ExpressRoutePort2 $portResource2 39 | ``` 40 | ### Example 3: Create 1 new circuit, and use existing circuit to get recommendation 41 | ``` 42 | $existingCircuit = Get-AzExpressRouteCircuit -Name $existingCircuitName -ResourceGroupName $resourceGroupName 43 | 44 | .\New-AzHighAvailabilityExpressRouteCircuits.ps1 -SubscriptionId $SubscriptionId -ResourceGroupName $resourceGroupName -Location "westus" -Name2 $circuitName -SkuFamily2 "MeteredData" -SkuTier2 "Standard" -ServiceProviderName2 "Equinix" -PeeringLocation2 "dallas" -BandwidthInMbps 1000 -ExistingCircuit $existingCircuit 45 | ``` -------------------------------------------------------------------------------- /expressroute/highAvailabilitySetup/New-AzHighAvailabilityExpressRouteCircuits.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory = $true)] 3 | [string]$SubscriptionId, 4 | 5 | [Parameter(Mandatory = $true)] 6 | [string]$ResourceGroupName, 7 | 8 | [Parameter(Mandatory = $true)] 9 | [string]$Location, 10 | 11 | [string]$Name1 = $null, 12 | 13 | [string]$Name2 = $null, 14 | 15 | [string]$SkuFamily1 = $null, 16 | 17 | [string]$SkuFamily2 = $null, 18 | 19 | [string]$SkuTier1 = $null, 20 | 21 | [string]$SkuTier2 = $null, 22 | 23 | [string]$ServiceProviderName1 = $null, 24 | 25 | [string]$ServiceProviderName2 = $null, 26 | 27 | [string]$PeeringLocation1 = $null, 28 | 29 | [string]$PeeringLocation2 = $null, 30 | 31 | [Parameter(Mandatory = $true)] 32 | [int]$BandwidthInMbps, 33 | 34 | [Microsoft.Azure.Commands.Network.Models.PSExpressRoutePort]$ExpressRoutePort1 = $null, 35 | 36 | [Microsoft.Azure.Commands.Network.Models.PSExpressRoutePort]$ExpressRoutePort2 = $null, 37 | 38 | [Microsoft.Azure.Commands.Network.Models.PSExpressRouteCircuit]$ExistingCircuit = $null 39 | ) 40 | 41 | Import-Module -Name Az.Network -WarningAction:SilentlyContinue 42 | 43 | function WriteRecommendation { 44 | param ( 45 | [string]$SubscriptionId, 46 | [string]$PeeringLocation1, 47 | [string]$PeeringLocation2 48 | ) 49 | 50 | $token = (Get-AzAccessToken).token 51 | $uri = "https://management.azure.com/subscriptions/$SubscriptionId/providers/Microsoft.Network/ExpressRoutePortsLocations?api-version=2023-09-01&includeAllLocations=true&relativeLocation=$PeeringLocation2" 52 | $headers = @{ 'Authorization' = "Bearer $token" } 53 | 54 | try { 55 | if ($PeeringLocation1 -ceq $PeeringLocation2) { 56 | Write-Error "Circuit 1 peering location ($($PeeringLocation1)) is the same as Circuit 2 peering location ($($PeeringLocation2)), please choose different peering locations to achieve high availability" 57 | exit 58 | } 59 | 60 | $locations = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers 61 | 62 | $distanceInKm = -1 63 | foreach ($location in $locations.value) { 64 | if ($location.name -eq $PeeringLocation1) { 65 | $distanceInKm = ([double]$location.properties.relativeDistanceOfPeeringLocations).ToString("N0"); 66 | } 67 | } 68 | 69 | $DistanceInMi = ([double]$distanceInKm / 1.6).ToString("N0") 70 | 71 | if ([double]$distanceInKm -lt 0) { 72 | Write-Host "`nRecommendation cannot be provided as distance between peering locations ($($PeeringLocation1)) and ($($PeeringLocation2)) is not found." 73 | exit 74 | } 75 | elseif ([double]$distanceInKm -eq 0) { 76 | Write-Host "`nDistance between peering locations ($($PeeringLocation1)) and ($($PeeringLocation2)) is 0. Please update one of the peering locations to achieve high availability." 77 | exit 78 | } 79 | else { 80 | if ([double]$distanceInKm -lt 242) { 81 | Write-Host "`nCircuit 1 peering location ($($PeeringLocation1)) is $($distanceInKm) km ($($DistanceInMi) miles) away from circuit 2 location ($($PeeringLocation2)). Based on the distance, it is recommended that the two circuits be used as High Available redundant circuits and the traffic be load balanced across the two circuits." 82 | } else { 83 | Write-Host "`nCircuit 1 peering location ($($PeeringLocation1)) is $($distanceInKm) km ($($DistanceInMi) miles) away from circuit 2 location ($($PeeringLocation2)). Based on the distance, it is recommended that the two circuits be used as redundant disaster recovery circuits and engineer traffic across the circuits by having one as active and the other as standby." 84 | } 85 | 86 | $response = Read-Host "`nPlease confirm you read the recommendation (Y/N)" 87 | if ($response -ne "Y" -and $response -ne "y") { 88 | exit 89 | } 90 | } 91 | 92 | } catch { 93 | Write-Error "`nFailed to retrieve distance between locations. $_" 94 | exit 95 | } 96 | } 97 | 98 | function GetPeeringLocation1FromExistingCircuit { 99 | param ( 100 | [Microsoft.Azure.Commands.Network.Models.PSExpressRouteCircuit]$ExistingCircuit 101 | ) 102 | 103 | try { 104 | if ($ExistingCircuit.ExpressRoutePort -ne $null -and $ExistingCircuit.ExpressRoutePort -ne ""){ 105 | $port = Get-AzExpressRoutePort -ResourceId $ExistingCircuit.ExpressRoutePort.Id 106 | return $port.PeeringLocation 107 | } 108 | else { 109 | return $ExistingCircuit.ServiceProviderProperties.PeeringLocation 110 | } 111 | } catch { 112 | Write-Error "`nFailed to retrieve peering location from existing circuit. $_" 113 | exit 114 | } 115 | } 116 | 117 | function ValidateBandwidth { 118 | param ( 119 | [int]$BandwidthInMbps, 120 | [string]$ExpressRoutePort1, 121 | [string]$ExpressRoutePort2 122 | ) 123 | if(($ExpressRoutePort1 -or $ExpressRoutePort2) -and $BandwidthInMbps % 1000 -ne 0) { 124 | Write-Error "`nBandwidthInMbps is set for both circuits. Since one of the circuits is created on port, allowed bandwidths in mbps are [1000, 2000, 5000, 10000, 40000, 100000]" 125 | exit 126 | } 127 | } 128 | 129 | 130 | #### Start of the main program 131 | 132 | if ($ExistingCircuit) { 133 | $PeeringLocation1 = GetPeeringLocation1FromExistingCircuit -ExistingCircuit $ExistingCircuit 134 | } 135 | 136 | if ($ExpressRoutePort1) { 137 | $PeeringLocation1 = $ExpressRoutePort1.PeeringLocation 138 | } 139 | 140 | if ($ExpressRoutePort2) { 141 | $PeeringLocation2 = $ExpressRoutePort2.PeeringLocation 142 | } 143 | 144 | # Check the distance and provide recommendations or fail operation if distance is 0 or less 145 | WriteRecommendation -SubscriptionId $SubscriptionId -PeeringLocation1 $PeeringLocation1 -PeeringLocation2 $PeeringLocation2 146 | 147 | # Validate bandwidth is available for the express route port, if one of the circuits are created on port 148 | ValidateBandwidth -BandwidthInMbps $BandwidthInMbps -ExpressRoutePort1 $ExpressRoutePort1 -ExpressRoutePort2 $ExpressRoutePort2 149 | 150 | $newGuid = [guid]::NewGuid() 151 | $tags = @{ 152 | "MaximumResiliency" = $newGuid.ToString() 153 | } 154 | 155 | try { 156 | # Create circuit 1 157 | if ($ExistingCircuit -eq $null) { 158 | Write "`nCreating circuit $($Name1)" 159 | if ($ServiceProviderName1) { 160 | New-AzExpressRouteCircuit -Name $Name1 -ResourceGroupName $ResourceGroupName -Location $Location -SkuTier $SkuTier1 -SkuFamily $SkuFamily1 -ServiceProviderName $ServiceProviderName1 -PeeringLocation $PeeringLocation1 -BandwidthInMbps $BandwidthInMbps -Tag $tags -WarningAction:SilentlyContinue 161 | } 162 | else { 163 | $BandwidthInGbps1 = $BandwidthInMbps / 1000 164 | $Location = $ExpressRoutePort1.Location 165 | New-AzExpressRouteCircuit -Name $Name1 -ResourceGroupName $ResourceGroupName -ExpressRoutePort $ExpressRoutePort1 -Location $Location -SkuTier $SkuTier1 -SkuFamily $SkuFamily1 -BandwidthInGbps $BandwidthInGbps1 -Tag $tags -WarningAction:SilentlyContinue 166 | } 167 | 168 | $circuit1 = Get-AzExpressRouteCircuit -Name $Name1 -ResourceGroupName $ResourceGroupName -WarningAction:SilentlyContinue 169 | if ($circuit1 -eq $null -or $circuit1.ProvisioningState -eq "Failed") { 170 | $errorMessage = "Failed to create circuit $($Name1) in location $($PeeringLocation1)" 171 | throw New-Object System.Exception($errorMessage) 172 | } 173 | } 174 | 175 | # Create cicuit 2 176 | Write "`nCreating circuit $($Name2)" 177 | if ($ServiceProviderName2) { 178 | New-AzExpressRouteCircuit -Name $Name2 -ResourceGroupName $ResourceGroupName -Location $Location -SkuTier $SkuTier2 -SkuFamily $SkuFamily2 -ServiceProviderName $ServiceProviderName2 -PeeringLocation $PeeringLocation2 -BandwidthInMbps $BandwidthInMbps -Tag $tags -WarningAction:SilentlyContinue 179 | } 180 | else { 181 | $BandwidthInGbps2 = $BandwidthInMbps / 1000 182 | $Location = $ExpressRoutePort2.Location 183 | New-AzExpressRouteCircuit -Name $Name2 -ResourceGroupName $ResourceGroupName -ExpressRoutePort $ExpressRoutePort2 -Location $Location -SkuTier $SkuTier2 -SkuFamily $SkuFamily2 -BandwidthInGbps $BandwidthInGbps2 -Tag $tags -WarningAction:SilentlyContinue 184 | } 185 | } catch { 186 | Write-Error "Failed to create circuits. $_" 187 | exit 188 | } 189 | -------------------------------------------------------------------------------- /expressroute/highAvailabilitySetup/New-AzHighAvailabilityVirtualNetworkGatewayConnections.md: -------------------------------------------------------------------------------- 1 | # New-AzHighAvailabilityVirtualNetworkGatewayConnections.ps1 2 | ## Syntax 3 | ``` 4 | New-AzHighAvailabilityVirtualNetworkGatewayConnections 5 | -SubscriptionId 6 | -ResourceGroupName 7 | -Location 8 | -VirtualNetworkGateway1 9 | [-Name1 ] 10 | -Name2 11 | [-Peer1 ] 12 | [-Peer2 ] 13 | [-PeerId1 ] 14 | [-PeerId2 ] 15 | [-RoutingWeight1 ] 16 | [-RoutingWeight2 ] 17 | [-ExpressRouteGatewayBypass1 ] 18 | [-ExpressRouteGatewayBypass1 ] 19 | [-ExistingVirtualNetworkGatewayConnection ] 20 | ``` 21 | 22 | ## Description 23 | The **New-AzHighAvailabilityVirtualNetworkGatewayConnections** cmdlet creates a pair of Azure express route virtual network gateway connections. 24 | 25 | ## Examples 26 | ### Example 1: Create 2 new connections. 27 | ``` 28 | .\New-AzHighAvailabilityVirtualNetworkGatewayConnections.ps1 -SubscriptionId -ResourceGroupName -Location -Name1 -Name2 -Peer1 $circuit1.Peerings[0] -Peer2 $circuit2.Peerings[0] -RoutingWeight1 10 -RoutingWeight2 10 -VirtualNetworkGateway1 $vng 29 | ``` 30 | ### Example 2: Create 1 new connection, and use existing connection to get recommendation 31 | ``` 32 | .\New-AzHighAvailabilityVirtualNetworkGatewayConnections.ps1 -SubscriptionId -ResourceGroupName -Location -Name2 -Peer2 $circuit1.Peerings[0] -RoutingWeight2 10 -VirtualNetworkGateway1 $vng -ExistingVirtualNetworkGatewayConnection $connection 33 | ``` -------------------------------------------------------------------------------- /expressroute/highAvailabilitySetup/New-AzHighAvailabilityVirtualNetworkGatewayConnections.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory = $true)] 3 | [string]$SubscriptionId, 4 | 5 | [Parameter(Mandatory = $true)] 6 | [string]$ResourceGroupName, 7 | 8 | [Parameter(Mandatory = $true)] 9 | [string]$Location, 10 | 11 | [string]$Name1 = $null, 12 | 13 | [Parameter(Mandatory = $true)] 14 | [string]$Name2 = $null, 15 | 16 | [Microsoft.Azure.Commands.Network.Models.PSPeering]$Peer1 = $null, 17 | 18 | [Microsoft.Azure.Commands.Network.Models.PSPeering]$Peer2 = $null, 19 | 20 | [string]$PeerId1 = $null, 21 | 22 | [string]$PeerId2 = $null, 23 | 24 | [Int32]$RoutingWeight1 = $null, 25 | 26 | [Parameter(Mandatory = $true)] 27 | [Int32]$RoutingWeight2 = $null, 28 | 29 | [string]$ExpressRouteGatewayBypass1 = $null, 30 | 31 | [string]$ExpressRouteGatewayBypass2 = $null, 32 | 33 | [Parameter(Mandatory = $true)] 34 | [Microsoft.Azure.Commands.Network.Models.PSVirtualNetworkGateway]$VirtualNetworkGateway1 = $null, 35 | 36 | [Microsoft.Azure.Commands.Network.Models.PSVirtualNetworkGatewayConnection]$ExistingVirtualNetworkGatewayConnection = $null 37 | ) 38 | 39 | Import-Module -Name Az.Network -WarningAction:SilentlyContinue 40 | 41 | function WriteRecommendation { 42 | param ( 43 | [string]$SubscriptionId, 44 | [string]$PeeringLocation1, 45 | [string]$PeeringLocation2 46 | ) 47 | 48 | $token = (Get-AzAccessToken).token 49 | $uri = "https://management.azure.com/subscriptions/$SubscriptionId/providers/Microsoft.Network/ExpressRoutePortsLocations?api-version=2023-09-01&includeAllLocations=true&relativeLocation=$PeeringLocation2" 50 | $headers = @{ 'Authorization' = "Bearer $token" } 51 | 52 | try { 53 | if ($PeeringLocation1 -ceq $PeeringLocation2) { 54 | Write-Error "Circuit 1 peering location ($($PeeringLocation1)) is the same as Circuit 2 peering location ($($PeeringLocation2)), please choose different peering locations to achieve high availability" 55 | exit 56 | } 57 | 58 | $locations = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers 59 | 60 | $distanceInKm = -1 61 | foreach ($location in $locations.value) { 62 | if ($location.name -eq $PeeringLocation1) { 63 | $distanceInKm = ([double]$location.properties.relativeDistanceOfPeeringLocations).ToString("N0"); 64 | } 65 | } 66 | 67 | $DistanceInMi = ([double]$distanceInKm / 1.6).ToString("N0") 68 | 69 | if ([double]$distanceInKm -lt 0) { 70 | Write-Host "`nRecommendation cannot be provided as distance between peering locations ($($PeeringLocation1)) and ($($PeeringLocation2)) is not found." 71 | exit 72 | } 73 | elseif ([double]$distanceInKm -eq 0) { 74 | Write-Host "`nDistance between peering locations ($($PeeringLocation1)) and ($($PeeringLocation2)) is 0. Please update one of the peering locations to achieve high availability." 75 | exit 76 | } 77 | else { 78 | if ([double]$distanceInKm -lt 242) { 79 | Write-Host "`nCircuit 1 peering location ($($PeeringLocation1)) is $($distanceInKm) km ($($DistanceInMi) miles) away from circuit 2 location ($($PeeringLocation2)). Based on the distance, it is recommended that the two circuits be used as High Available redundant circuits and the traffic be load balanced across the two circuits." 80 | } else { 81 | Write-Host "`nCircuit 1 peering location ($($PeeringLocation1)) is $($distanceInKm) km ($($DistanceInMi) miles) away from circuit 2 location ($($PeeringLocation2)). Based on the distance, it is recommended that the two circuits be used as redundant disaster recovery circuits and engineer traffic across the circuits by having one as active and the other as standby." 82 | } 83 | 84 | $response = Read-Host "`nPlease confirm you read the recommendation (Y/N)" 85 | if ($response -ne "Y" -and $response -ne "y") { 86 | exit 87 | } 88 | } 89 | 90 | } catch { 91 | Write-Error "`nFailed to retrieve distance between locations. $_" 92 | exit 93 | } 94 | } 95 | 96 | function GetPeeringLocationFromCircuitId { 97 | param ( 98 | [string]$PeerId 99 | ) 100 | 101 | try { 102 | $pattern = "/subscriptions/[^/]+/resourceGroups/([^/]+)/providers/Microsoft.Network/expressRouteCircuits/([^/]+)" 103 | 104 | if ($PeerId -match $pattern) { 105 | $resourceGroupName = $matches[1] 106 | $circuitName = $matches[2] 107 | } else { 108 | Write-Host "Resource group name and circuit name not found." 109 | } 110 | 111 | $circuit = Get-AzExpressRouteCircuit -ResourceGroupName $resourceGroupName -Name $circuitName -WarningAction:SilentlyContinue 112 | 113 | if ($circuit.ExpressRoutePort -ne $null -and $circuit.ExpressRoutePort -ne ""){ 114 | $port = Get-AzExpressRoutePort -ResourceId $circuit.ExpressRoutePort.Id 115 | return $port.PeeringLocation 116 | } 117 | else { 118 | return $circuit.ServiceProviderProperties.PeeringLocation 119 | } 120 | } catch { 121 | Write-Error "`nFailed to retrieve peering location from circuit. $_" 122 | exit 123 | } 124 | } 125 | 126 | #### Start of the main program 127 | 128 | if ($ExistingVirtualNetworkGatewayConnection -ne $null) { 129 | $PeerId1 = $ExistingVirtualNetworkGatewayConnection.Peer.Id 130 | } 131 | else { 132 | if ($Peer1 -ne $null) { 133 | $PeerId1 = $peer1.Id -replace "/peerings/AzurePrivatePeering.*", "" 134 | } 135 | else { 136 | $PeerId1 = $PeerId1 -replace "/peerings/AzurePrivatePeering.*", "" 137 | } 138 | } 139 | 140 | if ($Peer2 -ne $null) { 141 | $PeerId2 = $peer2.Id -replace "/peerings/AzurePrivatePeering.*", "" 142 | } 143 | else { 144 | $PeerId2 = $PeerId2 -replace "/peerings/AzurePrivatePeering.*", "" 145 | } 146 | 147 | $PeeringLocation1 = GetPeeringLocationFromCircuitId -PeerId $PeerId1 148 | $PeeringLocation2 = GetPeeringLocationFromCircuitId -PeerId $PeerId2 149 | 150 | # Check the distance and provide recommendations or fail operation if distance is 0 or less 151 | WriteRecommendation -SubscriptionId $SubscriptionId -PeeringLocation1 $PeeringLocation1 -PeeringLocation2 $PeeringLocation2 152 | 153 | try { 154 | # Create connection 1 155 | if ($ExistingVirtualNetworkGatewayConnection -eq $null) { 156 | Write "`nCreating first connection $($Name1)" 157 | New-AzVirtualNetworkGatewayConnection -Name $Name1 -ResourceGroupName $ResourceGroupName -Location $Location -VirtualNetworkGateway1 $VirtualNetworkGateway1 -ConnectionType "ExpressRoute" -RoutingWeight $RoutingWeight1 -PeerId $PeerId1 158 | 159 | $connection1 = Get-AzVirtualNetworkGatewayConnection -Name $Name1 -ResourceGroupName $ResourceGroupName -WarningAction:SilentlyContinue -ErrorAction:SilentlyContinue 160 | if ($connection1 -eq $null -or $circuit1.ProvisioningState -eq "Failed") { 161 | $errorMessage = "Failed to create connection $($Name1) in location $($PeeringLocation1)" 162 | throw New-Object System.Exception($errorMessage) 163 | } 164 | } 165 | 166 | # Create connection 2 167 | Write "`nCreating second connection $($Name2)" 168 | if ($Peer1 -ne $null) { 169 | $PeerId1 = $peer1.Id 170 | } 171 | 172 | New-AzVirtualNetworkGatewayConnection -Name $Name2 -ResourceGroupName $ResourceGroupName -Location $Location -VirtualNetworkGateway1 $VirtualNetworkGateway1 -ConnectionType "ExpressRoute" -RoutingWeight $RoutingWeight2 -PeerId $PeerId2 173 | 174 | $connection2 = Get-AzVirtualNetworkGatewayConnection -Name $Name2 -ResourceGroupName $ResourceGroupName -WarningAction:SilentlyContinue 175 | if ($connection2 -eq $null -or $circuit2.ProvisioningState -eq "Failed") { 176 | $errorMessage = "Failed to create connection $($Name2) in location $($PeeringLocation2)" 177 | throw New-Object System.Exception($errorMessage) 178 | } 179 | } catch { 180 | Write-Error "Failed to create connections. $_" 181 | exit 182 | } 183 | -------------------------------------------------------------------------------- /hdinsight/create-cluster/create-cluster.ps1: -------------------------------------------------------------------------------- 1 | function New-Cluster { 2 | # Script should stop on failures 3 | $ErrorActionPreference = "Stop" 4 | #####Start snippet line 5 5 | # Login to your Azure subscription 6 | $context = Get-AzContext 7 | if ($context -eq $null) 8 | { 9 | Connect-AzAccount 10 | } 11 | $context 12 | 13 | # If you have multiple subscriptions, set the one to use 14 | # $subscriptionID = "" 15 | # Select-AzSubscription -SubscriptionId $subscriptionID 16 | 17 | # Get user input/default values 18 | $resourceGroupName = Read-Host -Prompt "Enter the resource group name" 19 | $location = Read-Host -Prompt "Enter the Azure region to create resources in" 20 | 21 | # Create the resource group 22 | New-AzResourceGroup -Name $resourceGroupName -Location $location 23 | 24 | $defaultStorageAccountName = Read-Host -Prompt "Enter the name of the storage account" 25 | 26 | # Create an Az.Storage account and container 27 | New-AzStorageAccount ` 28 | -ResourceGroupName $resourceGroupName ` 29 | -Name $defaultStorageAccountName ` 30 | -Type Standard_LRS ` 31 | -Location $location 32 | $defaultStorageAccountKey = (Get-AzStorageAccountKey ` 33 | -ResourceGroupName $resourceGroupName ` 34 | -Name $defaultStorageAccountName)[0].Value 35 | 36 | $storageAccountResourceId = (Get-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $defaultStorageAccountName).Id 37 | 38 | $defaultStorageContext = New-AzStorageContext ` 39 | -StorageAccountName $defaultStorageAccountName ` 40 | -StorageAccountKey $defaultStorageAccountKey 41 | 42 | # Get information for the HDInsight cluster 43 | $clusterName = Read-Host -Prompt "Enter the name of the HDInsight cluster" 44 | # Cluster login is used to secure HTTPS services hosted on the cluster 45 | $httpCredential = Get-Credential -Message "Enter Cluster login credentials" -UserName "admin" 46 | # SSH user is used to remotely connect to the cluster using SSH clients 47 | $sshCredentials = Get-Credential -Message "Enter SSH user credentials" -UserName "sshuser" 48 | 49 | # Default cluster size (# of worker nodes), version, type, and OS 50 | $clusterSizeInNodes = "4" 51 | $clusterVersion = "5.1" 52 | $clusterType = "Hadoop" 53 | $clusterOS = "Linux" 54 | # Set the storage container name to the cluster name 55 | $defaultBlobContainerName = $clusterName 56 | 57 | # Create a blob container. This holds the default data store for the cluster. 58 | New-AzStorageContainer ` 59 | -Name $clusterName -Context $defaultStorageContext 60 | 61 | # Create the HDInsight cluster 62 | New-AzHDInsightCluster ` 63 | -ResourceGroupName $resourceGroupName ` 64 | -ClusterName $clusterName ` 65 | -Location $location ` 66 | -ClusterSizeInNodes $clusterSizeInNodes ` 67 | -ClusterType $clusterType ` 68 | -OSType $clusterOS ` 69 | -Version $clusterVersion ` 70 | -HttpCredential $httpCredential ` 71 | -StorageAccountResourceId $storageAccountResourceId ` 72 | -StorageAccountKey $defaultStorageAccountKey ` 73 | -StorageContainer $defaultBlobContainerName ` 74 | -SshCredential $sshCredentials 75 | #####End snippet line 71 76 | } 77 | -------------------------------------------------------------------------------- /managed-disks/create-managed-disks-from-vhd-in-different-subscription.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | 4 | .DESCRIPTION 5 | 6 | This sample demonstrates how to create a Managed Disk from a VHD file. 7 | Create Managed Disks from VHD files in following scenarios: 8 | 1. Create a Managed OS Disk from a specialized VHD file. A specialized VHD is a copy of VHD from an exisitng VM that maintains the user accounts, applications and other state data from your original VM. 9 | Attach this Managed Disk as OS disk to create a new virtual machine. 10 | 2. Create a Managed data Disk from a VHD file. Attach the Managed Disk to an existing VM or attach it as data disk to create a new virtual machine. 11 | 12 | .NOTES 13 | 14 | 1. Before you use this sample, please install the latest version of Azure PowerShell from here: http://go.microsoft.com/?linkid=9811175&clcid=0x409 15 | 2. Provide the appropriate values for each variable. Note: The angled brackets should not be included in the values you provide. 16 | 17 | 18 | #> 19 | 20 | #Provide the subscription Id 21 | $subscriptionId = 'yourSubscriptionId' 22 | 23 | #Provide the name of your resource group 24 | $resourceGroupName ='yourResourceGroupName' 25 | 26 | #Provide the name of the Managed Disk 27 | $diskName = 'yourDiskName' 28 | 29 | #Provide the size of the disks in GB. It should be greater than the VHD file size. 30 | $diskSize = '128' 31 | 32 | #Provide the URI of the VHD file that will be used to create Managed Disk. 33 | # VHD file can be deleted as soon as Managed Disk is created. 34 | # e.g. https://contosostorageaccount1.blob.core.windows.net/vhds/contoso-um-vm120170302230408.vhd 35 | $vhdUri = 'https://contosoststorageaccount1.blob.core.windows.net/vhds/contosovhd123.vhd' 36 | 37 | #Provide the resource Id of the storage account where VHD file is stored. 38 | #e.g. /subscriptions/6472s1g8-h217-446b-b509-314e17e1efb0/resourceGroups/MDDemo/providers/Microsoft.Storage/storageAccounts/contosostorageaccount 39 | $storageAccountId = '/subscriptions/yourSubscriptionId/resourceGroups/yourResourceGroupName/providers/Microsoft.Storage/storageAccounts/yourStorageAccountName' 40 | 41 | #Provide the storage type for the Managed Disk. PremiumLRS or StandardLRS. 42 | $sku = 'Premium_LRS' 43 | 44 | #Provide the Azure location (e.g. westus) where Managed Disk will be located. 45 | #The location should be same as the location of the storage account where VHD file is stored. 46 | #Get all the Azure location using command below: 47 | #Get-AzureRmLocation 48 | $location = 'westus' 49 | 50 | #Set the context to the subscription Id where Managed Disk will be created 51 | Set-AzContext -Subscription $subscriptionId 52 | 53 | #If you're creating an OS disk, add the following lines 54 | #Acceptable values are either Windows or Linux 55 | #$OSType = 'yourOSType' 56 | #Acceptable values are either V1 or V2 57 | #$HyperVGeneration = 'yourHyperVGen' 58 | 59 | #If you're creating an OS disk, add -HyperVGeneration and -OSType parameters 60 | $diskConfig = New-AzDiskConfig -SkuName $sku -Location $location -DiskSizeGB $diskSize -SourceUri $vhdUri -StorageAccountId $storageAccountId -CreateOption Import 61 | 62 | #Create Managed disk 63 | New-AzDisk -DiskName $diskName -Disk $diskConfig -ResourceGroupName $resourceGroupName 64 | -------------------------------------------------------------------------------- /storage/calculate-container-size/calculate-container-sizes-in-account.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Calculates the total size of blobs in all containers in a specified Azure storage account. 4 | 5 | .DESCRIPTION 6 | Before running this script, ensure you have: 7 | - A storage account created 8 | - At least one container in the storage account 9 | - Uploaded some blobs into the container 10 | 11 | .EXAMPLE 12 | .\Get-AzureStorageAccountBlobSize.ps1 -StorageAccountName mystorageaccount -ResourceGroupName myResourceGroup 13 | 14 | .NOTES 15 | This script incurs transactional costs for Azure requests. 16 | #> 17 | 18 | [CmdletBinding()] 19 | param ( 20 | [ValidateNotNullOrEmpty()] 21 | [string]$ResourceGroupName = '', 22 | 23 | [ValidateNotNullOrEmpty()] 24 | [string]$StorageAccountName = '' 25 | ) 26 | 27 | $containerstats = @() 28 | 29 | # Get a reference to the storage account and the context. 30 | $storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageAccountName 31 | $Ctx = $storageAccount.Context 32 | 33 | $container_continuation_token = $null 34 | do { 35 | $containers = Get-AzStorageContainer -Context $Ctx -MaxCount 5000 -ContinuationToken $container_continuation_token 36 | $container_continuation_token = $null 37 | 38 | if ($containers -ne $null) { 39 | $container_continuation_token = $containers[$containers.Count - 1].ContinuationToken 40 | 41 | for ([int] $c = 0; $c -lt $containers.Count; $c++) { 42 | $container = $containers[$c].Name 43 | Write-Verbose "Processing container : $container" 44 | $total_usage = 0 45 | $total_blob_count = 0 46 | $soft_delete_usage = 0 47 | $soft_delete_count = 0 48 | $version_usage = 0 49 | $version_count = 50 | $snapshot_count = 0 51 | $snapshot_usage = 0 52 | $blob_continuation_token = $null 53 | 54 | do { 55 | $blobs = Get-AzStorageBlob -Context $Ctx -IncludeDeleted -IncludeVersion -Container $container -ConcurrentTaskCount 100 -MaxCount 5000 -ContinuationToken $blob_continuation_token 56 | $blob_continuation_token = $null 57 | 58 | if ($blobs -ne $null) { 59 | $blob_continuation_token = $blobs[$blobs.Count - 1].ContinuationToken 60 | 61 | for ([int] $b = 0; $b -lt $blobs.Count; $b++) { 62 | $total_blob_count++ 63 | $total_usage += $blobs[$b].Length 64 | 65 | if ($blobs[$b].IsDeleted) { 66 | $soft_delete_count++ 67 | $soft_delete_usage += $blobs[$b].Length 68 | } 69 | 70 | if ($blobs[$b].SnapshotTime -ne $null) { 71 | $snapshot_count++ 72 | $snapshot_usage+= $blobs[$b].Length 73 | } 74 | 75 | if ($blobs[$b].VersionId -ne $null) { 76 | $version_count++ 77 | $version_usage += $blobs[$b].Length 78 | } 79 | } 80 | 81 | if ($blob_continuation_token -ne $null) { 82 | Write-Verbose "Blob listing continuation token = {0}".Replace("{0}",$blob_continuation_token.NextMarker) 83 | } 84 | } 85 | } while ($blob_continuation_token -ne $null) 86 | 87 | Write-Verbose "Calculated size of $container = $total_usage with soft_delete usage of $soft_delete_usage" 88 | $containerstats += [PSCustomObject] @{ 89 | Name = $container 90 | TotalBlobCount = $total_blob_count 91 | TotalBlobUsageinGB = $total_usage/1GB 92 | SoftDeletedBlobCount = $soft_delete_count 93 | SoftDeletedBlobUsageinGB = $soft_delete_usage/1GB 94 | SnapshotCount = $snapshot_count 95 | SnapshotUsageinGB = $snapshot_usage/1GB 96 | VersionCount = $version_count 97 | VersionUsageinGB = $version_usage/1GB 98 | } 99 | } 100 | } 101 | 102 | if ($container_continuation_token -ne $null) { 103 | Write-Verbose "Container listing continuation token = {0}".Replace("{0}",$container_continuation_token.NextMarker) 104 | } 105 | } while ($container_continuation_token -ne $null) 106 | 107 | Write-Host "Total container stats" 108 | $containerstats | Format-Table -AutoSize -------------------------------------------------------------------------------- /virtual-network-manager/automate-vnet-ip-address-management.ps1: -------------------------------------------------------------------------------- 1 | # automate-vnet-ip-address-management.ps1 2 | # Version: 1.0.1 3 | # Change log: Remove PID from script 4 | # Author: mbender-ms 5 | # Date: 2025-03-10 6 | # Description: This script automates the process of creating, associating, and disassociating Virtual Networks with IPAM Pools in Azure. It uses PowerShell to interact with Azure resources and manage IP address allocations efficiently. The script is designed to be run in a synchronous manner to ensure that no API calls fail such that they need to be retried. The script includes bulk creation of Virtual Networks using IpamPools reference, association of existing Virtual Networks using IpamPool reference, and disassociation of existing Virtual Networks using IpamPool reference. It is for demonstrtation purposes only and should not be used in production environments. 7 | 8 | # Prerequisites: 9 | # - Azure PowerShell module installed and configured, or Azure Cloud Shell 10 | # - Azure account with appropriate permissions to create and manage Virtual Networks, Azure Virtual Network Manager and IPAM Pools 11 | # - Valid Azure subscription ID and resource group name 12 | # - IPAM Pool reference ARM ID for creating and associating Virtual Networks 13 | 14 | # Run the script in Azure PowerShell or Azure Cloud Shell with appropriate permissions to create and manage Virtual Networks, Azure Virtual Network Manager and IPAM Pools. 15 | # This script is for demonstration purposes only and should not be used in production environments. 16 | # Note: The script uses the Az module for Azure PowerShell. Ensure you have the latest version of the Az module installed. 17 | 18 | 19 | # Set the variables for the script to your environment 20 | 21 | $location = "" # e.g. "East US", "West Europe", etc. 22 | $rgname = "" # use RG name as "*" to fetch all VNets from all RGs within subscription 23 | $sub = "" # use subscription id as "*" to fetch all VNets from all subscriptions within tenant 24 | $ipamPoolARMId = "" # e.g. "/subscriptions//resourceGroups//providers/Microsoft.Network/ipamPools/" 25 | $numberIPaddresses = "8" # Number of IP addresses to allocate from the IPAM Pool. This should be a valid number based on your IPAM Pool configuration. 26 | 27 | # Select your subscription 28 | Set-AzContext -Subscription $sub 29 | 30 | # Set the 31 | Write-Output "Starting creation of new VNets with IpamPool reference at: " (Get-Date).ToString("HH:mm:ss") 32 | $ipamPoolPrefixAllocation = [PSCustomObject]@{ 33 | Id = $ipamPoolARMId 34 | NumberOfIpAddresses = $numberIPaddresses 35 | } 36 | 37 | # Create 10 VNets using ipamPool reference - Change the number of VNets to create as needed in the for loop below 38 | for ($i = 0; $i -lt 10; $i++) { 39 | $subnetName = "defaultSubnet" 40 | $vnetName = "bulk-ipam-vnet-$i" 41 | $subnet = New-AzVirtualNetworkSubnetConfig -Name $subnetName -IpamPoolPrefixAllocation $ipamPoolPrefixAllocation -DefaultOutboundAccess $false 42 | $job = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname -Location $location -IpamPoolPrefixAllocation $ipamPoolPrefixAllocation -Subnet $subnet -AsJob 43 | $job | Wait-Job 44 | $actual = $job | Receive-Job 45 | } 46 | Write-Output "Starting creation of new VNets with IpamPool reference at: " (Get-Date).ToString("HH:mm:ss") 47 | 48 | # fetch all virtual networks from a resource group 49 | $vnetList = Get-AzVirtualNetwork -ResourceGroupName $rgname 50 | 51 | # bulk disassociation update 52 | Write-Output "Starting bulk disassociation for existing VNets at: " (Get-Date).ToString("HH:mm:ss") 53 | $ipamPoolPrefixAllocation = $null 54 | for ($i = 0; $i -lt @($vnetList).Count; $i++) { 55 | $vnetList[$i].AddressSpace.IpamPoolPrefixAllocations = $ipamPoolPrefixAllocation 56 | foreach ($subnet in $vnetList[$i].Subnets) { 57 | $subnet.IpamPoolPrefixAllocations = $ipamPoolPrefixAllocation 58 | } 59 | $job = Set-AzVirtualNetwork -VirtualNetwork $vnetList[$i] -AsJob 60 | $job | Wait-Job 61 | $actual = $job | Receive-Job 62 | } 63 | Write-Output "Starting bulk disassociation for existing VNets at: " (Get-Date).ToString("HH:mm:ss") 64 | 65 | # bulk association update 66 | Write-Output "Starting bulk association for existing VNets at: " (Get-Date).ToString("HH:mm:ss") 67 | $ipamPoolPrefixAllocation = [PSCustomObject]@{ 68 | Id = $ipamPoolARMId 69 | NumberOfIpAddresses = $numberIPaddresses 70 | } 71 | for ($i = 0; $i -lt @($vnetList).Count; $i++) { 72 | $vnetList[$i].AddressSpace.IpamPoolPrefixAllocations = $ipamPoolPrefixAllocation 73 | foreach ($subnet in $vnetList[$i].Subnets) { 74 | $subnet.IpamPoolPrefixAllocations = $ipamPoolPrefixAllocation 75 | } 76 | $job = Set-AzVirtualNetwork -VirtualNetwork $vnetList[$i] -AsJob 77 | $job | Wait-Job 78 | $actual = $job | Receive-Job 79 | } 80 | Write-Output "Finished bulk association for existing VNets at: " (Get-Date).ToString("HH:mm:ss") --------------------------------------------------------------------------------