├── .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")
--------------------------------------------------------------------------------