-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.xml
9449 lines (6419 loc) · 979 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>EUC365 | Modern Technology Blog</title>
<link>https://hugo.euc365.com/</link>
<description>Recent content on EUC365 | Modern Technology Blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>en</language>
<lastBuildDate>Wed, 31 May 2023 08:37:18 +0000</lastBuildDate><atom:link href="https://hugo.euc365.com/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Windows 365 Custom Images - Part 1 - The Foundations</title>
<link>https://hugo.euc365.com/post/windows-365-custom-images-part-1-foundations/</link>
<pubDate>Wed, 31 May 2023 08:37:18 +0000</pubDate>
<guid>https://hugo.euc365.com/post/windows-365-custom-images-part-1-foundations/</guid>
<description><p>Welcome along for the ride as we talk about Windows 365 Custom Images, and how we can use Azure Image Builder to create these images. In the upcoming series of posts, we will cover the following topics;</p>
<ul>
<li>Part 1 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-1-foundations/"><strong>The Foundations</strong></a> (This Post)</li>
<li>Part 2 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-2-powershell-deployment/"><strong>PowerShell Deployment</strong></a></li>
<li>Part 3 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-3-azure-devops-deployment/"><strong>DevOps Deployment</strong></a></li>
<li>Part 4 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-4-azure-avd-ui/"><strong>Azure Virtual Desktop UI Deployment</strong></a></li>
</ul>
<p>In this post we are going to discuss the foundations &amp; requirements for creating a custom images, it is intended that this post is read first before moving onto the other parts of the series to ensure you fully understand the required components and how they work together. So without any further ado, let&rsquo;s get started.</p>
<hr>
<h2 id="permission-requirements">Permission Requirements</h2>
<p>This first part of the series will cover the requirements for the Azure Infrastructure and the Azure Image Builder prerequisites, and as such will require the following permissions;</p>
<ul>
<li><strong>Owner</strong> permissions on the target Azure Subscription.</li>
</ul>
<p>Really, nothing more than that for creating the infrastructure.</p>
<hr>
<h2 id="what-is-azure-image-builder">What is Azure Image Builder?</h2>
<p>Azure Image Builder is a service that allows you to create custom images in Azure, this is based on HashiCorp Packer. Until recently, Image Templates had to be specified in either ARM (Azure Resource Manager) Templates, BICEP or you could use PowerShell to create your image. However, as of May 2023 there is a new kid on the block, you can now create images in the Azure Portal&hellip; see [<strong>Part 4</strong>] for more information on this.</p>
<hr>
<h2 id="what-will-we-need-to-create-for-the-foundations">What will we need to create for the Foundations?</h2>
<p>Well the answer is&hellip; not a lot and certainly nothing manually. This section is to first of all highlight what will be done in the Infrastructure setup script, and then we will go through the steps to execute the script. No one wants to blindly run it without knowing what it is doing&hellip;. Right?&hellip; Right?&hellip;</p>
<h3 id="azure-resource-group">Azure Resource Group</h3>
<p>This will come of no surprise to many, but we will need a resource group to store all of the resources we will create. This will be created in the subscription of your choice, and will have the name you specify with the <code>-aibRG</code> parameter. This will also be used to scope the permissions for the User Managed Identity and the Custom Role.</p>
<h3 id="custom-azure-role">Custom Azure Role</h3>
<p>Azure Image builder requires some specific permissions to be able to manage different aspects of the deployment. Rather than giving it full access to the subscription, we will create a custom role that will be scoped to the resource group we created above.</p>
<p>The role will have the following permissions;</p>
<ul>
<li><strong>Microsoft.Compute/galleries/read</strong></li>
<li><strong>Microsoft.Compute/galleries/images/read</strong></li>
<li><strong>Microsoft.Compute/galleries/images/versions/read</strong></li>
<li><strong>Microsoft.Compute/galleries/images/versions/write</strong></li>
<li><strong>Microsoft.Compute/images/write</strong></li>
<li><strong>Microsoft.Compute/images/read</strong></li>
<li><strong>Microsoft.Compute/images/delete</strong></li>
<li><strong>Microsoft.ManagedIdentity/userAssignedIdentities/assign/action</strong></li>
</ul>
<p>See the <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/linux/image-builder-permissions-powershell"><strong>Microsoft Documentation</strong></a> for more information on the permissions.</p>
<p>The <strong>Microsoft.ManagedIdentity/userAssignedIdentities/assign/action</strong> is not defined in the documentation, but is required when using Azure DevOps for Deployments using this solution.</p>
<h3 id="user-managed-identity">User Managed Identity</h3>
<p>The Azure Image Builder service requires a User Managed Identity to be able to perform the actions required to create the image. This will be created in the resource group we created above, and will be given the name of the resource group with the suffix of <strong>-UMI</strong>, unless you specify something different with the <code>-identityName</code> parameter.</p>
<p>Once the User Managed Identity has been created, it will be assigned the custom role we created above.</p>
<h3 id="azure-resource-providers">Azure Resource Providers</h3>
<p>To support the provisioning of the Azure resources within your subscription, the following resource providers will need to be registered;</p>
<ul>
<li><strong>Microsoft.Compute</strong></li>
<li><strong>Microsoft.Storage</strong></li>
<li><strong>Microsoft.VirtualMachineImages</strong></li>
<li><strong>Microsoft.Network</strong></li>
<li>(Optional) <strong>Microsoft.KeyVault</strong> - This is only required if you are using a Key Vault to store your secrets.</li>
</ul>
<p>Documentation can be found on this <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/windows/image-builder-powershell#register-features">LINK</a>.</p>
<h2 id="deploying-the-foundations">Deploying the Foundations</h2>
<p>Now we understand what the script will do, let&rsquo;s go through the steps to execute the script. The script can be found on my GitHub repository, and can be downloaded from the link below;</p>
<p><a href="https://github.com/brookd2404/windows365/blob/main/Custom%20Images/Create-AIBInfrastructure.ps1"><img src="http://euc365.com/images/git_resource.png" alt="GitHub Resource"></a></p>
<p>The <strong>Create-AIBInfrastructure.ps1</strong> script, once executed will install the required PowerShell modules, and then prompt you to login to Azure.</p>
<p>Below is an example of the parameters that can be used to execute the script;</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-posh" data-lang="posh"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$splat = @{
</span></span><span style="display:flex;"><span> SubscriptionID = <span style="color:#e6db74">&#34;b493a1f9-4895-45fe-bb71-152b36eea469&#34;</span> <span style="color:#75715e"># The ID of the Azure Subscription where the resources will be created.</span>
</span></span><span style="display:flex;"><span> geoLocation = <span style="color:#e6db74">&#34;UKSouth&#34;</span> <span style="color:#75715e"># The Azure region in which resources will be provisioned</span>
</span></span><span style="display:flex;"><span> aibRG = <span style="color:#e6db74">&#34;W365-CI-EUC365&#34;</span> <span style="color:#75715e"># The name of the resource group to be created</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>.\Create-AIBInfrastructure.ps1 @splat
</span></span></code></pre></div></br>
<p>Once the script is executed, you will start to see the resource information in the console;</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/foundationExecute_hued813d45066a380b444f1d6f23611c53_97552_750x0_resize_q100_h2_box_3.webp" alt="Foundation Script Execution Output" height="" width="100%">
</br>
<p>Once the execution has complete you will have a resource group with the Custom Roles &amp; the User Managed Identity with the Custom Role assigned to it.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/foundationRG_hu64e7c07917baf29ec5f79875b729408e_52537_750x0_resize_q100_h2_box_3.webp" alt="Resource Group" height="" width="85%">
<hr>
<h2 id="conclusion">Conclusion</h2>
<p>Stick around and check our the other parts of the series noted in the introduction, and if you have any questions or comments, please feel free to reach out to me on Twitter or leave a comment below.</p>
</description>
</item>
<item>
<title>Windows 365 Custom Images - Part 2 - PowerShell Deployment</title>
<link>https://hugo.euc365.com/post/windows-365-custom-images-part-2-powershell-deployment/</link>
<pubDate>Wed, 31 May 2023 08:37:10 +0000</pubDate>
<guid>https://hugo.euc365.com/post/windows-365-custom-images-part-2-powershell-deployment/</guid>
<description><p>Welcome to the second post in the series talking about Windows 365 Custom Images, and how we can use Azure Image Builder to create these images. In this series of posts, we will cover the following topics;</p>
<ul>
<li>Part 1 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-1-foundations/"><strong>The Foundations</strong></a></li>
<li>Part 2 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-2-powershell-deployment/"><strong>PowerShell Deployment</strong></a> (This Post)</li>
<li>Part 3 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-3-azure-devops-deployment/"><strong>DevOps Deployment</strong></a></li>
<li>Part 4 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-4-azure-avd-ui/"><strong>Azure Virtual Desktop UI Deployment</strong></a></li>
</ul>
<p>The first post in the series covered the foundations for all of the deployment methods, and as such, this post will cover the PowerShell deployment method. We will cover additional requirements and what to expect as an output from the script.</p>
<p>The PowerShell deployment method will not only create the Image, but it will also upload the image to the Windows 365 Service, and then create a new Windows 365 Cloud PC Provisioning Policy, or update and existing policy if one already exists.</p>
<hr>
<div class="notices note" ><p>The ids in the script are fictitious and for example purposes only, please do not use these in your environment.</p></div>
<h2 id="permission-requirements">Permission Requirements</h2>
<p>As we are executing this manually, the <strong>Owner</strong> permission on the Subscription is not required, you will require the following permissions to execute the script;</p>
<ul>
<li><strong>Intune Administrator</strong></li>
<li><strong>Contributor</strong> on the Resource Group where the resources will be created</li>
</ul>
<hr>
<h2 id="getting-prepared">Getting Prepared</h2>
<p>Before we can execute the script, we will need to ensure that we gather all of the information we will need to execute the script and achieve our goal of creating a custom image for Windows 365.</p>
<h3 id="image-offer-and-sku">Image Offer and SKU</h3>
<p>One of the first things we need to obtain is the Image Offer we will use as our base template. To do so, follow the below steps;</p>
<ol>
<li>Obtain the <a href="https://github.com/brookd2404/Powershell_Scripts/blob/master/Azure/Get-ImageOptions.ps1"><strong>Get-ImageOptions.ps1</strong></a> script</li>
<li>Run this script, specifying your Subscription ID, Geo Locations (e.g UKSouth, EastUS etc.) and the Image Publisher (which for this case is MicrosoftWindowsDesktop), as below.</li>
</ol>
<p><code>Get-ImageOptions.ps1 -SubscriptionId &lt;Subid&gt; -geoLocation &quot;UKSouth&quot; -imagePublisher &quot;MicrosoftWindowsDesktop&quot;</code></p>
<ol start="3">
<li>Locate the <strong>windows-ent-cpc</strong> heading, and take note of an image offer you wish to use.</li>
</ol>
<p>For those wondering, this denotes <strong>Windows Enterprise Cloud PC</strong>. There are two options for later versions of the OS, which are M365 or OS. To help make your decision, please review the <a href="https://learn.microsoft.com/en-us/windows-365/enterprise/device-images#gallery-images"><strong>Cloud PC Device images overview</strong></a> documentation.</p>
<h2 id="image-customisations">Image Customisations</h2>
<p>As you will see in the script, there are three customisations, two &lsquo;Inline&rsquo; and 1 script URI. Now these are the bits that make your images do the business, there is a bit of trial and error some times, but when you find your groove, it becomes like shelling peas.</p>
<p>If you search for <code>$ImgCustomParams</code> this will locate the customisations. If you add, or remove one, please do not forget to update the <code>$ImgTemplateParams</code> object!, more information on customiser objects in PowerShell can be found <a href="https://learn.microsoft.com/en-us/powershell/module/az.imagebuilder/new-azimagebuildertemplatecustomizerobject?view=azps-10.0.0&amp;viewFallbackFrom=azps-9.1.0"><strong>HERE</strong></a>.</p>
<p>You can use the Managed Identity to access Azure Storage Accounts for Files, there is documentation on this <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/linux/image-builder-user-assigned-identity#"><strong>HERE</strong></a>, this is not in in a PowerShell formate but it does outline the concept.</p>
<div class="notices tip" ><p>Generation 2 Virtual Machine Templates require both <strong>RunAsSystem</strong> &amp; <strong>RunAsElevated</strong> to be set to <strong>True</strong>. If you do not do this, the image will fail to build.</p></div>
<hr>
<h2 id="executing-the-script">Executing the Script</h2>
<p>Ok, lets get some resources in the over, go grab a coffee, and come back to a fully built image, and a new Windows 365 Provisioning Policy&hellip; honestly, this process from start to finish takes longer than 1 hour&hellip; Why not use a Windows 365 to do it to avoid any unexpected interruptions 😋😋!!</p>
<div class="notices note" ><p>This script will create a shared image gallery where the image will be built to before creating the Managed disk. This is to also provide additional value in that you can create multiple images in the same gallery, and then use the same image for multiple purposes. For example, you could create a Windows 10 Enterprise image, and then use this for both Windows 365 and Azure Virtual Desktop.</p></div>
<p>To execute the script, ensure you have added your Customisations and gathered all the information you need to pass into the script, and then execute the script as the below example;</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-posh" data-lang="posh"><span style="display:flex;"><span>$Params = @{
</span></span><span style="display:flex;"><span> subscriptionID = <span style="color:#e6db74">&#34;b493a1f9-4895-45fe-bb71-152b36eea469&#34;</span> <span style="color:#75715e">#The ID of the Azure Subscription where the resources will be created.</span>
</span></span><span style="display:flex;"><span> geoLocation = <span style="color:#e6db74">&#34;uksouth&#34;</span> <span style="color:#75715e">#The Azure region in which resources will be provisioned.</span>
</span></span><span style="display:flex;"><span> aibRG = <span style="color:#e6db74">&#34;w365-CICD-rg&#34;</span> <span style="color:#75715e">#The name of the resource group to be created</span>
</span></span><span style="display:flex;"><span> imageTemplateName = <span style="color:#e6db74">&#34;w365CustomCICD&#34;</span> <span style="color:#75715e">#The name of the Image Template to Create.</span>
</span></span><span style="display:flex;"><span> aibGalleryName = <span style="color:#e6db74">&#39;sigw365&#39;</span> <span style="color:#75715e">#The name of the Image Gallery to create/update, You cannot use special characters or spaces in this field.</span>
</span></span><span style="display:flex;"><span> imageDefinitionName = <span style="color:#e6db74">&#39;w365Images&#39;</span> <span style="color:#75715e">#The name of the image definition to create</span>
</span></span><span style="display:flex;"><span> provisioningPolicyDisplayName = <span style="color:#e6db74">&#34;W365 Demo&#34;</span> <span style="color:#75715e">#The name of your Windows 365 Provisioning Policy.</span>
</span></span><span style="display:flex;"><span> publisher = <span style="color:#e6db74">&#34;MicrosoftWindowsDesktop&#34;</span> <span style="color:#75715e">#This value is set by default, but please do update to suit your needs, please see the Image Offer and SKU section above</span>
</span></span><span style="display:flex;"><span> offerName = <span style="color:#e6db74">&#34;windows-ent-cpc&#34;</span> <span style="color:#75715e">#This value is set by default, but please do update to suit your needs, please see the Image Offer and SKU section above</span>
</span></span><span style="display:flex;"><span> offerSku = <span style="color:#e6db74">&#34;win11-22h2-ent-cpc-m365&#34;</span> <span style="color:#75715e">#This value is set by default, but please do update to suit your needs, please see the Image Offer and SKU section above</span>
</span></span><span style="display:flex;"><span> runOutputName = <span style="color:#e6db74">&#34;w365DistResult&#34;</span> <span style="color:#75715e">#The Result Output Name.</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&amp; <span style="color:#e6db74">&#39;.\Create-Windows365AIB.ps1&#39;</span> @Params
</span></span></code></pre></div><p>Don&rsquo;t worry, you will be able to see it is still working though, as the script will check the progress on actions periodically, and output information to the console&hellip; I have been there, and I know the feeling of &lsquo;is it still working&rsquo; 🤣🤣&hellip;</p>
<h2 id="conclusion">Conclusion</h2>
<p>So there you have it, a fully automated (yet Manually Invoked) image build process for Windows 365, and a new Windows 365 Provisioning Policy. Stick around for the next post in the series, where we will cover the Azure DevOps deployment method for a complete hands off approach to deploying your Windows 365 Custom Images.</p>
<p>If you have any questions, please do reach out to me on Twitter or in the comments below.</p>
</description>
</item>
<item>
<title>Windows 365 Custom Images - Part 3 - Azure DevOps Deployment</title>
<link>https://hugo.euc365.com/post/windows-365-custom-images-part-3-azure-devops-deployment/</link>
<pubDate>Wed, 31 May 2023 08:37:04 +0000</pubDate>
<guid>https://hugo.euc365.com/post/windows-365-custom-images-part-3-azure-devops-deployment/</guid>
<description><p>Welcome to the third post in the series talking about Windows 365 Custom Images, and how we can use Azure Image Builder to create these images. In this series of posts, we will cover the following topics;</p>
<ul>
<li>Part 1 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-1-foundations/"><strong>The Foundations</strong></a></li>
<li>Part 2 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-2-powershell-deployment/"><strong>PowerShell Deployment</strong></a></li>
<li>Part 3 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-3-azure-devops-deployment/"><strong>DevOps Deployment</strong></a> (This Post)</li>
<li>Part 4 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-4-azure-avd-ui/"><strong>Azure Virtual Desktop UI Deployment</strong></a></li>
</ul>
<p>Some of you may be like Veruca Salt from Charlie and the Chocolate Factory, and want all of the goodies <strong>Now</strong> and opted to jump the second post in the series, and well, that is fine, I would have done the same thing 🤣, sorry not sorry.</p>
<p>In this post, we will be looking at how we can use Azure DevOps to deploy our Windows 365 Custom Image. Please follow the process carefully, as missing any of the steps could leave you scratching your head as to why it is not working.</p>
<div class="notices info" ><p>This post assumes you have basic source control competency, and that you are familiar with the terminology such as, pull, push etc. If you are not, then I would recommend you read up on this before continuing.</br>You will also need to have the ability to use Git on your workstation.</p></div>
<hr>
<h2 id="permission-requirements">Permission Requirements</h2>
<p>For this post, we do need some additional permissions, however these can be short lived as once we configure the pipelines, service principals etc, we will only need the ability to manage the source data.</p>
<h3 id="azure-devops">Azure DevOps</h3>
<ul>
<li>You will need the ability to Create a Project in Azure DevOps</li>
<li>You will need the ability to Create a Service Connection in an Azure DevOps Project</li>
<li>Have at least 1 Self-Hosted Agent or 1 Microsoft Hosted Agent available to run the pipeline (Free Tier is fine, the code is designed to run from a free tier account) - <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&amp;tabs=yaml"><strong>Documentation on Agents</strong></a></li>
</ul>
<div class="notices warning" ><p>The free agents have a maximum run time of 1 hour and there are also limitations on monthly execution limits. As we go through this guide, you will notice that there are two pipelines to work around this been a problem.</p></div>
<h3 id="azure">Azure</h3>
<ul>
<li><strong>Global Administrator</strong> permissions to create the Service Principal &amp; grant the required Application Permissions.</li>
</ul>
<hr>
<h2 id="getting-prepared">Getting Prepared</h2>
<h3 id="azure-devops-project--service-connection">Azure DevOps Project &amp; Service Connection</h3>
<p>First of all, lets get the Azure DevOps Project created, I would recommend following the <a href="https://learn.microsoft.com/en-us/azure/devops/organizations/projects/create-project?view=azure-devops&amp;tabs=browser"><strong>Microsoft Documentation</strong></a> on this. The name of the project is not important, but I would recommend using something that is meaningful to you.</p>
<p>Once you have the project created, we will need to create a Service Connection, again I would recommend following the <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&amp;tabs=yaml"><strong>Microsoft Documentation</strong></a>, ensuring you select <strong>Resource Group</strong> created in the Foundations post and you select <strong>Grant access permission to all pipelines</strong>.</p>
<h3 id="service-principal-app-registration">Service Principal (App Registration)</h3>
<p>You only need to run through this section if you want to upload the image to Windows 365, which I assume you do. If you do not, then you can skip this section.</p>
<p>Not that it&rsquo;s a habit of this post&hellip; but I have another link&hellip; this time it&rsquo;s to one of my previous posts, <a href="https://hugo.euc365.com/create_an_azure_app_registration/"><strong>Create an Azure App Registration</strong></a>, the service principal will need the following permissions;</p>
<ul>
<li><strong>CloudPC.ReadWrite.All</strong> - This is required to upload the image to Windows 365</li>
<li>It will also need the <strong>Custom</strong> Role assigning on the resource group you created in the Foundations post. (By default this will be called <strong>Azure Image Builder Image Definition for <code>&lt;Resource Group Name&gt;</code></strong>)</li>
</ul>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/roleUMI_hu69e4290da9899aa02ab231893e9f5679_24893_749x0_resize_q100_h2_box_3.webp" alt="Role UMI Assignment" height="" width="">
</br>
<p>Once you have the Service Principal created, you will need to create a secret, and take note of the <strong>Application (client) ID</strong> and <strong>Client Secret</strong> &amp; the <strong>Tenant ID</strong> for later use.</p>
<hr>
<h2 id="the-code">The Code</h2>
<p>Ok, now we are ready to start getting into the juicy bits!!</p>
<p>Before we go any further, you will need to ensure you have cloned your repository to your local machine, ready to copy the code into the Azure DevOps Project.</p>
<p>You can get all of the code using the GitHub Resource link below.</p>
<p><a href="https://github.com/brookd2404/windows365/tree/main/Custom%20Images/Azure%20DevOps"><img src="http://euc365.com/images/git_resource.png" alt="GitHub Resource"></a></p>
<p>Once you have download the code, and copied it into your local repository, we can start to update the code to suit your needs.</p>
<h3 id="image-template-bicep">Image Template (BICEP)</h3>
<p>The Image template file itself is located in the <strong>Templates</strong> folder, and is called <strong>Windows365.bicep</strong>. The only edits we need to make to this file for the purpose of this guide is the <strong>customizations</strong>, this is where we will define the applications we want to install on the image along with any other scripted or inline customization.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/bicepcustomise_hue12491a4e3059e3eaf7fb4e6b7897415_36145_750x0_resize_q100_h2_box_3.webp" alt="BICEP File Customisations" height="" width="">
</br>
<p>As you will see above there are two marked areas, the <strong>RED</strong> area is where you will define the customisation objects and the <strong>YELLOW</strong> area is a sample of what the customisation object looks like. You can read about more BICEP customisations objects <a href="https://learn.microsoft.com/en-us/azure/templates/microsoft.virtualmachineimages/imagetemplates?pivots=deployment-language-bicep#imagetemplatecustomizer-objects"><strong>HERE</strong></a>.</p>
<p>Once you have made all your customisations, we can move onto looking at the parameters file.</p>
<h3 id="parameters">Parameters</h3>
<p>You will notice from the codeset, that there is a parameters file, this is what drives the BICEP file (Apart from Customisations) in the Templates folder.</p>
<p>Separating the parameters from the BICEP file, allows us to use the same BICEP file for multiple deployments, without having to edit the BICEP file each time.</p>
<p>If we open up the <strong>Windows365.parameters.json</strong> file and take a look at the parameters that are available to set, all of which have descriptions to help you understand what they are for.</p>
<p>There is one key parameters that you will need to set that is unique to your environment, that is the <strong>AIBMSIName</strong> parameter. This is the name of the User Managed Identity in you resource group. If you are unsure of the name, you can find this in the Azure Portal, by navigating to the resource group you created in the Foundations post.</p>
<p>All of the other parameters are set to default values, which you can change if you wish, but the image would provision with the default values.</p>
<h3 id="pipelines-yaml">Pipelines (YAML)</h3>
<p>As mentioned in the Getting Prepared section, we will be using two pipelines to cater for those using the free tier of Azure DevOps. The first pipeline will be used to create the image template and then invoke the build of the Managed Image, and the second pipeline will be used to upload the image to Windows 365.</p>
<div class="notices tip" ><p>If you are using a paid pipeline, you can combine the two pipelines into one, you will just need to ensure all of the correct variables are set and that you do not have any duplicate steps.</p></div>
<h4 id="pipeline-1---create-image-template--build-managed-image">Pipeline 1 - Create Image Template &amp; Build Managed Image</h4>
<h5 id="pipeline-name---createmanagedimageyaml">Pipeline Name - CreateManagedImage.yaml</h5>
<p>This pipeline will create the image template and then invoke the build of the Managed Image, there are a couple of variables that you will need to update prior to running the pipeline, these are;</p>
<ul>
<li><strong>Connection</strong> - The name of the Azure DevOps Service Connector with access to subscription (Created Above)</li>
<li><strong>subscriptionID</strong> - The subscription ID of the subscription you are deploying to</li>
<li><strong>resourceGroup</strong> - The name of the resource group you created in the Foundations post</li>
<li><strong>imageTemplateName</strong> - A name for the image template you want to create</li>
<li><strong>location</strong> - The region you want to deploy the resources to, i.e &ldquo;UK South&rdquo;</li>
<li><strong>template</strong> - Path to the BICEP file e.g. <strong>Templates/Windows365.bicep</strong></li>
<li><strong>templateParameters</strong> - Path to the parameters file e.g. <strong>Parameters/Windows365.parameters.json</strong></li>
</ul>
<div class="notices tip" ><p>You will notice a commented out section in the pipeline, this section will allow you to create a schedule to run the pipeline on.</p></div>
<p>This pipeline also handles some other actions, such as clearing up existing templates, as this is not currently possible. We will cover the DeploymentActions.ps1 file in a later section.</p>
<h4 id="pipeline-2---upload-image-to-windows-365">Pipeline 2 - Upload Image to Windows 365</h4>
<h5 id="pipeline-name---deploytow365yaml">Pipeline Name - DeployToW365.yaml</h5>
<p>This pipeline will upload the image to Windows 365, again there are a couple of variables that you will need to update prior to running the pipeline, these are the same as above. However, we will be adding Pipeline Variables later in the post once we have published the code, and created the pipeline in DevOps.</p>
<h4 id="deploymentactionsps1">DeploymentActions.ps1</h4>
<p>This script can be thought of as a boilerplate script, it is used to handle some of the actions that we run in a PowerShell script, this is customisable to your needs.</p>
<p>If you wish to amend the Provisioning Profile type, data etc, this can be found in this script, the same goes for the Required Modules sections of the script.</p>
<hr>
<h3 id="publish-the-code--createrun-the-pipelines">Publish the Code &amp; Create/Run the Pipelines</h3>
<p>Once you have updated the code to suit your needs, you will need to push the code to your Azure DevOps Project and then we can head over to Azure DevOps to create the pipelines.</p>
<p>Ok, so first of all, let us create the pipeline to create the image template and build the managed image.</p>
<ol>
<li>Open your DevOps Project</li>
<li>In the left hand menu, select <strong>Pipelines</strong></li>
<li>Click <strong>Create Pipeline</strong></li>
<li>Select <strong>Azure Repos Git</strong></li>
<li>Select your repository</li>
<li>Select <strong>Existing Azure Pipelines YAML file</strong></li>
<li>Select the <strong>CreateManagedImage.yaml</strong> file, and click <strong>Continue</strong></li>
</ol>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/pipemanimage_hudeec81268b330ab108800f6c522c3040_18507_479x0_resize_q100_h2_box_3.webp" alt="Create Managed Pipeline" height="" width="">
<ol start="8">
<li>Check the details in the pipeline, and click <strong>Run</strong></li>
</ol>
<p>Ok, now we have the first pipeline running, we can create the second pipeline to upload the image to Windows 365.</p>
<ol>
<li>In the left hand menu, select <strong>Pipelines</strong></li>
<li>Click <strong>New Pipeline</strong> (Top Right)</li>
<li>Select <strong>Azure Repos Git</strong></li>
<li>Select your repository</li>
<li>Select <strong>Existing Azure Pipelines YAML file</strong></li>
<li>Select the <strong>DeployToW365.yaml</strong> file, and click <strong>Continue</strong></li>
</ol>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/pipedeploy_huffd282c64140e230de438d3f9b6bb626_18148_475x0_resize_q100_h2_box_3.webp" alt="Create Deploy Pipeline" height="" width="">
<ol start="7">
<li>Click <strong>Variables</strong></li>
<li>Click <strong>New variable</strong></li>
<li>Enter <strong>ClientID</strong> in the <strong>Name</strong> field, and the <strong>Application (client) ID</strong> from the Service Principal you created earlier in the <strong>Value</strong> field, and click <strong>OK</strong></li>
<li>Click the <strong>+</strong> icon in the top right of the variables section</li>
<li>Enter <strong>ClientSecret</strong> in the <strong>Name</strong> field, and the <strong>Client Secret</strong> from the Service Principal you created earlier in the <strong>Value</strong> field, select <strong>Keep this value secret</strong> and click <strong>OK</strong></li>
<li>Click the <strong>+</strong> icon in the top right of the variables section</li>
<li>Enter <strong>TenantID</strong> in the <strong>Name</strong> field, and the <strong>Directory (tenant) ID</strong> from the Service Principal you created earlier in the <strong>Value</strong> field, and click <strong>OK</strong></li>
</ol>
<p>You should end up with something that looks like this;</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/variables_hud9efc08a6bb0eab0d48ef34c3fab449f_9776_479x0_resize_q100_h2_box_3.webp" alt="Deploy Pipeline Variables" height="" width="">
<p>This time don&rsquo;t click <strong>Run</strong>, instead use the dropdown next to it and click <strong>Save</strong>. We will amend the name of the Pipeline by clicking the ellipses next to the <strong>Run Pipeline</strong> button (Top Right), and then clicking <strong>Rename/Move</strong>. Once you have renamed your pipeline, you can click <strong>Run Pipeline</strong>.</p>
<p>When you click run, it will queue this job and it will wait for the first pipeline to complete, before running.</p>
<h4 id="sample-outputs">Sample Output(s)</h4>
<h5 id="overview-of-pipelines">Overview of Pipelines</h5>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/pipelinesoverview_hud8fd705d8e95f858ad27dfca40aa306b_25407_750x0_resize_q100_h2_box_3.webp" alt="Overview of Pipelines" height="" width="">
</br>
<h5 id="create-managed-image-pipeline">Create Managed Image Pipeline</h5>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/pipeline1_huca642fd523260eb418be34325ecc07ba_64621_750x0_resize_q100_h2_box_3.webp" alt="Create Managed Image Pipeline" height="" width="">
</br>
<h5 id="deploy-to-windows-365-pipeline">Deploy to Windows 365 Pipeline</h5>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/pipeline2_hucf13e8f87123791a75d7c22b8d8e1d5f_66682_750x0_resize_q100_h2_box_3.webp" alt="Deploy to Windows 365 Pipeline" height="" width="">
</br>
<h5 id="windows-365-image-in-the-console">Windows 365 Image In the Console</h5>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/w365Portal_hub792f1d997280632cb8ce8e8538634b1_26697_750x0_resize_q100_h2_box_3.webp" alt="Windows 365 Image" height="" width="">
<hr>
<h2 id="conclusion">Conclusion</h2>
<p>Well this has been a fun post, this is by far the most in-depth post in the series, but man is it worth it!!</p>
<p>Stick around for the next post in the series, where we will be looking at how to create Image templates with the new UI Features in Azure Virtual Desktop within the Azure Portal.</p>
<p>As always, if you have any questions, please feel free to reach out to me on Twitter or leave a comment below.</p>
</description>
</item>
<item>
<title>Windows 365 Custom Images - Part 4 - Azure AVD UI</title>
<link>https://hugo.euc365.com/post/windows-365-custom-images-part-4-azure-avd-ui/</link>
<pubDate>Wed, 31 May 2023 08:36:57 +0000</pubDate>
<guid>https://hugo.euc365.com/post/windows-365-custom-images-part-4-azure-avd-ui/</guid>
<description><p>Welcome to the fourth (&amp; final&hellip; for now) post in the series talking about Windows 365 Custom Images, and how we can use Azure Image Builder to create these images. In this series of posts, we will cover the following topics;</p>
<ul>
<li>Part 1 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-1-foundations/"><strong>The Foundations</strong></a></li>
<li>Part 2 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-2-powershell-deployment/"><strong>PowerShell Deployment</strong></a></li>
<li>Part 3 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-3-azure-devops-deployment/"><strong>DevOps Deployment</strong></a></li>
<li>Part 4 - <a href="https://hugo.euc365.com/post/windows-365-custom-images-part-4-azure-avd-ui/"><strong>Azure Virtual Desktop UI Deployment</strong></a> (This Post)</li>
</ul>
<p>This has been a long time coming for people not so involved with ARM, BICEP, DevOps or PowerShell as there is now UI Capabilities for you to create your own custom images. You can even use some &lsquo;in-built&rsquo; customisation options to give you that extra hand along the way.</p>
<p>This is by far the most manually involved piece, but it is a great way to get started with Azure Image Builder, and then you can start to explore the other options available to you.</p>
<p>So without further ado, lets get into it!</p>
<div class="notices note" ><p>You must still use the Foundation post to create the required resources, as this post will not cover the creation of the required resources.</p></div>
<hr>
<h2 id="permission-requirements">Permission Requirements</h2>
<p>For this post, you will need access to the Subscription and Resource Group created in the Foundations post. During Testing no other permissions were required, but as with everything this may change in the future.</p>
<hr>
<h2 id="getting-prepared">Getting Prepared</h2>
<p>Ok, before we start getting into the creating of the template, ensure you have the publicly available links to your resources, even if you are using something with a SAS token or in a storage account, it needs to be accessible from the internet.</p>
<div class="notices tip" ><p>If you are using the Managed Identity to get data from a storage account, please ensure that this has the relevant permissions on that account.</p></div>
<h2 id="creating-the-image">Creating the Image</h2>
<p>So we are now ready to start creating the image, so let&rsquo;s head over to the <a href="https://portal.azure.com"><strong>Azure Portal</strong></a> and then head to the <strong>Azure Virtual Desktop</strong> blade.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/avdblade_hu778898063c6d8de5e701e77fbfb39d16_26113_750x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop blade" height="" width="">
</br>
<p>Once you are in the Azure Virtual Desktop blade, you will need to select the <strong>Custom image templates</strong> option from the left hand menu.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/avdcioptions_hu2801852e31a0583f0516b511f91b5fad_11105_272x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop Custom Image Option" height="" width="">
<hr>
<h3 id="create-a-custom-image">Create a Custom Image</h3>
<div class="notices info" ><p>The same rule still applies here, you cannot currently update an image template. However, you will see as you go through the UI Selection options, it will give you the ability to select a previous template to use as a base. We won&rsquo;t cover that here, but I wanted to make you aware of it.</p></div>
<ol>
<li>Click <strong>Add custom image template</strong> from the ribbon</li>
<li>Enter the follwing information on the basic pane;</li>
</ol>
<ul>
<li><strong>Template Name</strong>: The name you wish to call the image template</li>
<li><strong>Import from existing template</strong>: If you have a previous template you wish to use as a base, select it here, other wise select <strong>No</strong></li>
<li><strong>Subscription</strong>: The subscription your resource group is in</li>
<li><strong>Resource Group</strong>: The resource group you created in the Foundations post</li>
<li><strong>Location</strong>: The region you wish to deploy the image to</li>
<li><strong>Managed Identity</strong>: The Managed Identity created in the Foundations post</li>
</ul>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/avdcibasic_hu9012fe3d09e45c478a3ea5eedea1725f_22846_750x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop Custom Image Basic Blade" height="80%" width="80%">
</br>
<ol start="3">
<li>On the <strong>Source Image</strong> pane, enter the following details;</li>
</ol>
<ul>
<li><strong>Source Type</strong>: For this post we will be using a <strong>Platform Image</strong>, but if you have other image types you can explore them here.</li>
<li><strong>Select Image</strong>: Select the image you wish to use as a base for your custom image (If you choose a Windows 10 Image, I recommend using the ones appended with Gen2)</li>
</ul>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/selectsource_huf3006c8c85dd3f8fcf4cacd5f7c8f095_38458_750x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop Custom Image Source Blade" height="80%" width="">
</br>
<ol start="4">
<li>On the <strong>Distribution Targets</strong> pane, enter the following details, and then click <strong>Next</strong>;</li>
</ol>
<ul>
<li><strong>Managed Image</strong>: Select this option as this is what we are focusing on in this post</li>
<li><strong>Resource Group</strong>: Select the resource group you created in the Foundations post</li>
<li><strong>Image Name</strong>: The name you wish to call the image</li>
<li><strong>Location</strong>: The region you wish to deploy the image to</li>
<li><strong>Run output name</strong>: The name you wish to call the run output</li>
</ul>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/disttarget_hua0fd067a64de8c83b0ad172a60722fbd_37601_750x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop Custom Image Distribution Blade" height="80%" width="80%">
</br>
<ol start="5">
<li>
<p>On the <strong>Build Properties</strong> Pane, we can leave all options as default. However, this is where you could add a VNET, increase the size of the packer VM to improve build speed etc. for now we can just click <strong>Next</strong>.</p>
</li>
<li>
<p>Ok, now we are onto the <strong>Customizations</strong> pane, this is where you will add in links to your scripts, or use the built-in scripts to help tailor the experience for your needs. Feel free to play around here and then click <strong>Next</strong>.</p>
</li>
</ol>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/portalcustomisations_hu79d20c7044884d8d8ae77709ee2d5ef5_41833_750x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop Custom Image Customizations Blade" height="" width="">
</br>
<ol start="7">
<li>
<p>Add any tags you wish to add to the image, and then click <strong>Next</strong>.</p>
</li>
<li>
<p>Review the information you have entered, and then click <strong>Create</strong>.</p>
</li>
</ol>
<p>Once you click create, you will be taken back to the Custom Image Templates blade, and you will see your new template being created, this normally only takes a few minutes, but the image is not quite ready at this point.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/creatingtemplate_hua61144197f9d8016b8906ee91fa352ae_68081_750x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop Custom Image Template" height="" width="">
</br>
<p>Once the template status changes to to <strong>Success</strong>, you can select the template and then click <strong>Run</strong> from the ribbon.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/startbuild_hu33487020f63f5569ef2d7a7314802443_52830_727x0_resize_q100_h2_box_3.webp" alt="Azure Virtual Desktop Custom Image Template - start build" height="" width="">
</br>
<p>This process creation time can vary, it all depends on the customisations you have added, and the size of the image you are creating, go grab a coffee and come back in a little while.</p>
<hr>
<h2 id="uploading-the-image-to-windows-365">Uploading the Image to Windows 365</h2>
<p>A little while later&hellip; we can finally upload the image to Windows 365.</p>
<p>Lets start by heading over to the <a href="https://intune.microsoft.com"><strong>Intune Console</strong></a> and then head to the <strong>Devices Windows 365</strong> blade.</p>
<p>From here we need to select the <strong>Custom Images</strong> tab, and then click <strong>Add</strong> from the ribbon. The configuration menu will appear to the right of the screen, where you should enter the following information;</p>
<ul>
<li><strong>Image Name</strong>: The display name of the image in Windows 365</li>
<li><strong>Image Version</strong>: A version number for the image, I use the date format, for example 22.05.26.</li>
<li><strong>Subscription</strong>: The subscription your image is in</li>
<li><strong>Source Image</strong>: The image you created in the previous section</li>
</ul>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/w365ImageConfig_hub6630b53745c50f9e1843fbcde86210d_21626_325x0_resize_q100_h2_box_3.webp" alt="Intune Windows 365 Custom Image Configuration" height="" width="">
</br>
<p>Once you have entered the information, click <strong>Add</strong> and you will see the image appear in the list, once the upload completes, the status will change to <strong>Upload successful</strong> and be available for selection in the provisioning policy.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/w365/customimage/w365ImageList_huff17fe2c60f360e05021906c2344c47b_36591_750x0_resize_q100_h2_box_3.webp" alt="Intune Windows 365 Custom Image List" height="" width="">
<hr>
<h2 id="conclusion">Conclusion</h2>
<p>I love that this is now making image creation more accessible to admins, however I find this the most labour intensive process as with the PowerShell and DevOps options, you can automate the process, and not have to worry about checking the status of the image creation &amp; upload.</p>
<p>I hope you have enjoyed this series, and I hope it has helped you on your journey to Windows 365 with Custom Images.</p>
<p>As always, if you have any questions, please feel free to reach ou t to me on Twitter or leave a comment below.</p>
</description>
</item>
<item>
<title>ASR Custom Data Collection with Intune</title>
<link>https://hugo.euc365.com/post/asr-custom-data-collection-intune/</link>
<pubDate>Wed, 24 May 2023 20:05:23 +0000</pubDate>
<guid>https://hugo.euc365.com/post/asr-custom-data-collection-intune/</guid>
<description><p>At MMS MOA 2023, I presented a session alongside <a href="https://twitter.com/KennyBuntinx"><strong>Kenny Buntinx</strong></a> on Attack Surface Reduction (ASR) rules, a session filled with lessons learnt, interaction and belgian chocolate. During this session, I showed a custom data collection script that I had written to collect the ASR events from the event log and send them to a Log Analytics workspace, and then how to inject that data into a Power BI report.</p>
<p>This post will cover the configuration of the Power BI Report and the Intune Remediation Script, to help you better report on ASR events in your environment, without having to pay for an E5 license.</p>
<hr>
<h2 id="getting-prepared">Getting Prepared</h2>
<p>First of all, you will need a Log Analytics Workspace, if you don&rsquo;t have one already, you can create one in the Azure Portal. Once you have the workspace created, we will need the <strong>Workspace ID</strong> and <strong>Primary Key</strong> for the workspace, these can be found in the <strong>Agents</strong> section of the workspace.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/asr/lawsinfo_hu9ce6f959a1af8a672cd6f46c85599429_98095_750x0_resize_q100_h2_box_3.webp" alt="Log Analytics Workspace" height="" width="100%">
</br>
<p>The second thing we will need is the Intune Remediation Script, this is available for download from the below button. The script will need to be configured with the <strong>Workspace ID</strong> and <strong>Primary Key</strong> from the Log Analytics Workspace at a minimum, there are other configurable options in the script, but these are optional, and are noted in the HelpMessage of the parameters.</p>
<p>Once the script has been amended, the information on how to configure the tested configuration within Intune is available in the <strong>README</strong> file in the repository.</p>
<p><a href="https://github.com/brookd2404/IntunePRs/tree/main/Inventory/ASR%20Events"><img src="http://euc365.com/images/git_resource.png" alt="GitHub Resource"></a></p>
<hr>
<h2 id="configuring-the-power-bi-report">Configuring the Power BI Report</h2>
<p>Ok, so this section is to assume that there is now data flowing into the Log Analytics Workspace, as without the data, the report will be empty.</p>
<p>The first thing we need to do in this section is create an Azure App Registration that can be used to access both the Log Analytics Workspace and the Graph API.</p>
<p>To do this, we will need to create a new App Registration in the Azure Portal, and give it the following Graph API <strong>Application</strong> permissions:</p>
<ul>
<li><strong>DeviceManagementManagedDevices.Read.All</strong></li>
</ul>
<p>You can follow my guide on how to create an App Registration <a href="https://hugo.euc365.com/create_an_azure_app_registration/"><strong>here</strong></a>, and then how to grant access to the Log Analytics Workspace <a href="https://hugo.euc365.com/post/log-analytics-api-data-access-service-principals/"><strong>here</strong></a>.</p>
<p>Once the App Registration has been created, we will need to download the Power BI Report, from the below button, and open it in Power BI Desktop.</p>
<p><a href="https://github.com/brookd2404/powerbi/tree/main/ASR"><img src="http://euc365.com/images/git_resource.png" alt="GitHub Resource"></a></p>
<p>When you first open the report, you will be prompted to enter the following information:</p>
<ul>
<li><strong>Tenant ID</strong> - This is the tenant ID of the Azure AD Tenant</li>
<li><strong>Application ID</strong> - This is the Application ID of the App Registration</li>
<li><strong>Application Secret</strong> - An application secret key of the App Registration</li>
<li><strong>Log Analytics Workspace ID</strong> - This is the Workspace ID of the Log Analytics Workspace</li>
</ul>
<p>You will also need to select the Timeframe you wish to query from a drop down list, however this is further configurable in the report itself.</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/asr/reportconfig_hu80eabda50e35a15cf71c2db25414a828_18047_700x0_resize_q100_h2_box_3.webp" alt="Power BI Report Configuration" height="" width="">
</br>
<p>Once you click <strong>Load</strong>, you will be prompted about privacy levels, ensure you configure these as Public for the purposes of this guide, this is the only configuration that has been tested and confirmed working. This will then initiate the data load from the API&rsquo;s and Log Analytics Workspace.</p>
<p>Once the Data has been loaded, you will be presented with the following report visual:</p>
<img loading="lazy" decoding="async" class="mx-auto d-block" src="https://hugo.euc365.com/images/post/asr/reportpreview_hua7dc859dbcce61fddb146d67c42340c1_167370_750x0_resize_q100_h2_box_3.webp" alt="Power BI Report Preview" height="" width="">
</br>
<p>Once you click on an Event in the bottom left-hand table, the event data will be displayed to the right-hand side to help you make informed decisions on your data.</p>
<hr>
<h2 id="credits--conclusion">Credits &amp; Conclusion</h2>
<p>This post utilises frameworks of the Guys and Girls over at <a href="https://msendpointmgr.com/"><strong>MSEndpointMGR</strong></a>, the function used to post the data to the LAW is based on a function used in other inventory collection scripts.</p>
<p>You can also look to further secure you data collection by utilising one of their other framworks which utilises Azure Function Apps (<a href="https://msendpointmgr.com/2022/01/17/securing-intune-enhanced-inventory-with-azure-function/"><strong>SEE HERE</strong></a>)</p>
<p>I hope you find this post useful, and if you have any questions, please reach out to me or leave a comment below.</p>
</description>
</item>
<item>
<title>Graph API & Power BI - MMS Edition</title>
<link>https://hugo.euc365.com/post/intune-power-bi-mms-edition/</link>
<pubDate>Fri, 19 May 2023 13:37:08 +0000</pubDate>
<guid>https://hugo.euc365.com/post/intune-power-bi-mms-edition/</guid>
<description><p>What a blast this year at <a href="https://mmsmoa.com"><strong>MMS MOA</strong></a> 2023!!. The time last year I spoke for the first time and did a quick 3 minute session in Tips &amp; Tricks and this year (2023) I returned as a speaker, with an improved and fleshed out Power BI Session alongside <a href="https://hugo.euc365.com/author/steve-beumont"><strong>Steve Beaumont</strong></a>. Some may recall my previous post <a href="https://hugo.euc365.com/microsoft-graph-and-powerbi/"><strong>Microsoft Graph API and PowerBI</strong></a>, there will be some reference back to this as we go through this one.</p>
<p>We covered a lot on stage, and this post is here to help flesh out those configuration area&rsquo;s that we didn&rsquo;t cover in the session, and also has the link to the goodies for you to start the journey to feature rich reports with Intune &amp; Power BI.</p>
<h2 id="getting-prepared">Getting Prepared</h2>
<p>As per the previous <a href="https://hugo.euc365.com/microsoft-graph-and-powerbi/"><strong>post</strong></a>, we will still be using a service principal to access the data, however we will also be expanding this scope to allowing data read access to your log analytics workspace.</p>
<p>The dataset that is available for download has the following <strong>Application</strong> API permission requirements for Intune and AAD:</p>
<ul>
<li><strong>DeviceManagementManagedDevices.Read.All</strong> (Intune Devices Data &amp; Autopilot Events)</li>
<li><strong>Device.Read.All</strong> (AAD Data - Device)</li>
<li><strong>User.Read.All</strong> (AAD Data - User)</li>
</ul>
<p>For information on creating a service principal (App Registration) and assigning the permissions, please refer to one of my previous <a href="https://hugo.euc365.com/create_an_azure_app_registration/"><strong>post</strong></a>.</p>
<p>Aside from the above, we also need to grant access to the Log Analytics Workspace that holds the Windows Update for Business reports data, please refer to the following <a href="https://hugo.euc365.com/post/log-analytics-api-data-access-service-principals/"><strong>post</strong></a> for more information on how to grant access to the service principal.</p>