-
Notifications
You must be signed in to change notification settings - Fork 0
/
ReferenceFile1.02.02.ps1
1486 lines (1343 loc) · 84.5 KB
/
ReferenceFile1.02.02.ps1
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
<#
ReferenceFile
by Dan Felman/HP Inc
Script will parse an HPIA reference file and provides a means to remove or replace a Softpaq
solution with a superseded version
The working reference file is updated as changes are made to the Solutions selections. This
working file is to be used with HPIA /ReferenceFile:<file.xml> runtime option
06/20/2023 1.00.01 - initial release
06/28/2023 1.01.01 - major rewrite to improve replace functionality, added debug output info
06/28/2023 1.01.02 - added 'debug output' check (for troubleshooting)
06/29/2023 1.01.03 - new offline repo group, init repo, populate
07/06/2023 1.01.10 - added repo selection, init, and sync desired Softpaqs
07/07/2023 1.01.11 - improved repo selection, more debug output
07/10/2023 1.01.12 - added: debug output to log file in script folder, change from 'Load' to 'Lod File'
07/10/2023 1.01.13 - rearranged GUI items for clear info
07/11/2023 1.01.14 - cleanup, test release to customers
07/12/2023 1.01.15 - fix action output issues, additional cleanup of existing repo prior to reuse
07/17/2023 1.01.16 - prevent 'replace' button from enable if Supersede list is empty
03/29/2024 1.01.17 - Added 23H2 support to selection list
04/03/2024 1.02.01 - added selection by driver type (Network, Storage, Graphics, etc.)
param(
[Parameter( Mandatory = $false )]$CacheDir, # for future use
[Parameter( Mandatory = $false )]$ReferenceFile # for future use
) # param
#>
$ReFileVersion = '1.02.02'
'ReferenceFile.ps1 - '+$ReFileVersion+' (Apr-16-2024)'
###################################################################################
$Script:OSs = @('10','11') # what shows on the GUI entry box
$Script:OS10Vers = @('2009','21H1','21H2','22H2')
$Script:OS11Vers = @('21H2','22H2','23H2','24H2')
###################################################################################
$Script:OS
$Script:OSVer
$Script:RefFilePath = $null # working reference file path
$Script:DebugInfo = $true
# check for CMSL - required to run this script
Try {
$Error.Clear()
Get-HPDeviceDetails -ErrorAction SilentlyContinue > $null
} Catch {
$error[0].exception # $error[0].exception.gettype().fullname
return
}
# Set up the Cache folder path that hosts the downloaded/unpacked reference file
if ( $Script:CacheDir -eq $null ) {
$Script:CacheDir = $Pwd.Path
}
$Script:CacheDir = (Convert-Path $Script:CacheDir)
$Script:LogFilePath = $Script:CacheDir+'\ReferenceFile.log'
<#################################################################################
Function Get_FileFromHP
1) retrieves latest reference file, saves to cache folder
(using CMSL Get-SofptaqList)
2) finds downloaded reference (xml) file
3) copies file from cache folder to current folder
replacing file if same file name exists in folder
Returns: path of reference file in current folder
#################################################################################>
Function Get_FileFromHP {
[CmdletBinding()] param( $pPlatform, $pOS, $pOSVer )
if ( $Script:DebugInfo ) { ">> Get_FileFromHP() - platform: $pPlatform - OS $pOS/$pOSVer" | out-file -append $Script:LogFilePath }
$gr_CacheDir = (Convert-Path $Pwd.Path)
$gr_Path = $null
# let's download a reference file and create a copy to work on
Try {
$Error.Clear()
get-softpaqList -platform $pPlatform -OS $pOS -OSVer $pOSVer -Overwrite 'Yes' -CacheDir $gr_CacheDir -EA SilentlyContinue | Out-Null
# find the downloaded Reference_File.xml file
$gr_XmlFile = Get-Childitem -Path $gr_CacheDir'\cache' -Include "*.xml" -Recurse -File |
where { ($_.Directory -match '.dir') -and ($_.Name -match $pPlatform) `
-and ($_.Name -match $pOS.Substring(3)) -and ($_.Name -match $pOSVer) }
Copy-Item $gr_XmlFile -Destination $Pwd.Path -Force # make a copy to the working directory (where the script runs from)
# and return the path to the XML file in the working folder
$gr_Path = "$($Pwd.Path)\$($gr_XmlFile.Name)" # final destination in current folder
} Catch {
write-host 'Reference File failure' -ForegroundColor yellow
write-host $error[0].exception # $error[0].exception.gettype().fullname
}
if ( $Script:DebugInfo ) { "<< Get_FileFromHP() - Downloaded file for: $pPlatform/$pOS/$pOSVer" | out-file -append $Script:LogFilePath }
if ( $Script:DebugInfo ) { "<< Get_FileFromHP() - Using: $gr_Path" | out-file -append $Script:LogFilePath }
return $gr_Path # final destination, if found
} # Function Get_FileFromHP
<#################################################################################
Function Get_LocalFile
1) copies reference file argument to the caching folder
2) if file with same reference file name exists in
current folder, renames it as .bak (only once)
3) copies file from cache folder to current folder
Returns: path of reference file in current folder
#################################################################################>
Function Get_LocalFile {
[CmdletBinding()] param( $pReferenceFile )
if ( $Script:DebugInfo ) { ">> Get_LocalFile() - reference: $pReferenceFile" | out-file -append $Script:LogFilePath }
$gr_FileReturn = $null
if ( Test-Path $pReferenceFile ) {
$gr_RefFileNameNoExt = [System.IO.Path]::GetFileNameWithoutExtension($pReferenceFile)
$gr_RefFilePath = Split-Path -Path $pReferenceFile -Parent
$gr_RefFileBakFullPath = $gr_RefFilePath+'\'+$gr_RefFileNameNoExt+'.bak'
# make a backup of reference file from arg to a .bak version
Copy-Item -Path $pReferenceFile -Destination $gr_RefFileBakFullPath -Force
$gr_FileReturn = $pReferenceFile
} else {
'-- Reference File does not exist'
return $gr_FileReturn
} # else if ( Test-Path $pReferenceFile )
if ( $Script:DebugInfo ) { "<< Get_LocalFile() - Using: $pReferenceFile" | out-file -append $Script:LogFilePath }
return $gr_FileReturn
} # Function Get_LocalFile
<######################################################################################
Function Get_UWPInfo
This functions determines if the Softpaq has a UWP requirement and if it is installed
Parms: $pCVAMetadata: content of all CVA metadata file
$pInstalledAppxName: registry list of UWP/appx installed in system
Returns: the Softpaq UWP name and version, and (if) installed the UWP version
[0] UWP full name - from reference file store info section (or $null)
[1] UWP version - from reference file store info section (or $null)
[2] UWP version - from installed UWP store info section (or $null)
#>#####################################################################################
Function Get_UWPInfo {
[CmdletBinding()] param( $pCVAMetadata, $pInstalledAppxName )
if ( $Script:DebugInfo ) { ">> Get_UWPInfo() - app name to find: $pInstalledAppxName" | out-file -append $Script:LogFilePath }
$gu_SoftpaqID = $pCVAMetadata.Softpaq.SoftpaqNumber
$gu_CVAUWPFullName = $null
$gu_CVAUWPName = $null
$gu_CVAUWPVersion = $null
if ( $pCVAMetadata.Private.MS_Store_App -eq 1 ) {
# find the UWP package info from the CVA file
[array]$gu_UWPPackageList = $pCVAMetadata.'Store Package Info'.Values
foreach ( $iPkgFullName in $gu_UWPPackageList ) {
$gu_UWPPackageHash = $iPkgFullName.split('_')
if ( $gu_UWPPackageHash[0] -eq $pInstalledAppxName ) {
$gu_CVAUWPFullName = $iPkgFullName
$gu_CVAUWPName = $gu_UWPPackageHash[0] # ex. NVIDIAControlPanel
$gu_CVAUWPVersion = $gu_UWPPackageHash[1] # ex. 8.1.962.0
break
} # if ( $gu_UWPPackageHash[0] -eq $pInstalledAppxName )
} # foreach ( $iPkgFullName in $gu_UWPPackageList )
} # if ( $pCVAMetadata.Private.MS_Store_App -eq 1 )
if ( $Script:DebugInfo ) {
if ( $gu_CVAUWPVersion ) {
" Get_UWPInfo() Softpaq: $($gu_SoftpaqID)" | out-file -append $Script:LogFilePath
" ... [0] App Full Name: $($gu_CVAUWPFullName)" | out-file -append $Script:LogFilePath
" ... [1] Version: $($gu_CVAUWPVersion)" | out-file -append $Script:LogFilePath
} else {
" < Get_UWPInfo() Softpaq: $($gu_SoftpaqID) - NO UWP found" | out-file -append $Script:LogFilePath
}
} # if ( $Script:DebugInfo )
return $gu_CVAUWPFullName, $gu_CVAUWPVersion
} # Function Get_UWPInfo
<#################################################################################
Function Show_SoftpaqList
find and display entries from the reference file in form textbox
returns number of listed Softpaqs
Args: $pFormList # GUI TextBox list to display Solutions
$pXMLSolutions # node list from XML reference file
$pCategories # list of categories to match when showing Solutions
# ... currently using simple 'match' of categories
$pNameMatch # name of Softpaq to match for listing
$pDriverType # array/list of driver types
Return: Number of Solutions displayed
#################################################################################>
Function Show_SoftpaqList {
[CmdletBinding()]
param( $pFormList, $pXMLSolutions, [array]$pCategories, $pSearchName, [array]$pDriverType )
$pFormList.Items.Clear()
$ss_ListCount = 0
foreach ( $iSoftpaq in $pXMLSolutions ) { # loop thru every Solution (Softpaq)
$ss_addEntry = $false
$ss_searchNameMatch = $false
if ( $pCategories ) {
# check for the Sofptaq category being selected
foreach ( $iCat in $pCategories ) {
if ( $iSoftpaq.Category -match $iCat ) { # ex. 'BIOS - System Firmware'
switch ($iCat) {
'BIOS' { if ( $iSoftpaq.Category -like "BIOS*" ) { $ss_addEntry = $true } }
'Firmware' { if ( $iSoftpaq.Category -notlike "BIOS*" ) { $ss_addEntry = $true } }
'Driver' { $ss_addEntry = $true
if ( $pDriverType.count -gt 0 ) {
$ss_addEntry = $false
$pDriverType | ForEach-Object {
if ( $iSoftpaq.Category -match $_ ) { $ss_addEntry = $true }
}
} # if ( $pDriverType )
} # 'Driver'
'Software' { $ss_addEntry = $true }
'Dock' { $ss_addEntry = $true }
} # switch ($iCat)
if ( $ss_addEntry ) { break }
} # if ( $iSoftpaq.category -match $iCat )
} # foreach ( $iCat in $pCategories )
} else {
$ss_addEntry = $true # no Category selected, so add the Softpaq to the list
} # else if ( $pCategories )
if ( $ss_addEntry ) {
# is there a Softpaq name search going on?
if ( ($null -ne $pSearchName) -and ($iSoftpaq.name -match $pSearchName) ) {
$ss_searchNameMatch = $true
}
if ( $null -eq $pSearchName -or ($ss_searchNameMatch) ) {
$ss_Entry = "$($iSoftpaq.id) $($iSoftpaq.name) / $($iSoftpaq.version) / $($iSoftpaq.DateReleased)"
[void]$pFormList.items.add($ss_Entry)
$ss_ListCount += 1
}
} # if ( $ss_addEntry )
} # foreach ( $iSoftpaq in $ss_XMLSolutions ) {
return $ss_ListCount
} # Function Show_SoftpaqList
<#################################################################################
Function List_Supersedes
shows superseded entries in form superseded textbox
Obtains the lists directly from the XML reference file
Args: $pssFormList # GUI TextBox to display SUperseded Solutions for selected Solution
$pSoftpaqID # Softpaq ID to match
Returns: no return
#################################################################################>
Function List_Supersedes {
[CmdletBinding()] param( $pssFormList, $pSoftpaqID )
$pssFormList.Items.Clear()
$ls_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
$ls_ssXMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions-Superseded/UpdateInfo")
# find the selected Softpaq node in /Solutions
$ls_Node = $ls_XMLSolutions | where { $_.id -eq $pSoftpaqID }
# now, search for more entries in the SS chain
while ( $null -ne $ls_Node.Supersedes ) {
$ls_Node = $ls_ssXMLSolutions | where { $_.id -eq $ls_Node.Supersedes }
$ls_TmpEntry = "$($ls_Node.id) $($ls_Node.name) / $($ls_Node.version) / $($ls_Node.DateReleased)"
[void]$pssFormList.items.add($ls_TmpEntry)
} # while ( $null -ne $ls_Node.Supersedes)
} # Function List_Supersedes
Function Get_SoftpaqCategory {
[CmdletBinding()] param( $pSoftpaqID )
$gs_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
$gs_Node = $gs_XMLSolutions | where { $_.id -eq $pSoftpaqID }
return $gs_Node.Category
} # Get_SoftpaqCategory
<#################################################################################
Function Remove_XMLUWPApps
Handle specifics of removing a UWP entry from the reference file...
Called by a Driver or Software Softpaq removal function
Args: $pSolutionNode # the Software solution to use for UWP search
Return: # of UWP entries removed
#################################################################################>
Function Remove_XMLUWPApps {
[CmdletBinding()] param( $pSolutionNode )
if ( $Script:DebugInfo ) { ">> Remove_XMLUWPApps() - Solution: $($pSolutionNode.Name)" | out-file -append $Script:LogFilePath }
$rx_RemovedUWPCount = 0
$rx_XMLUWPInstalled = $Script:xmlContent.SelectNodes("ImagePal/SystemInfo/UWPApps/UWPApp")
$rx_UWPNode = $rx_XMLUWPInstalled | Where-Object { $_.Solutions.UpdateInfo.IdRef -eq $pSolutionNode.Id }
foreach ( $i_UWPNode in [array]$rx_UWPNode ) {
$rx_UWPFullName = $i_UWPNode.Name
$i_UWPNode.ParentNode.RemoveChild($i_UWPNode) | Out-Null
if ( $Script:DebugInfo ) { ".. Remove_XMLUWPApps() removed UWP: $rx_UWPFullName" | out-file -append $Script:LogFilePath }
$rx_RemovedUWPCount += 1
}
if ( $Script:DebugInfo ) { ">> Remove_XMLUWPApps() - removed: $rx_RemovedUWPCount" | out-file -append $Script:LogFilePath }
return $rx_RemovedUWPCount
} # Function Remove_XMLUWPApps
<#################################################################################
Function Remove_XMLDevices
Handle specifics of removing devices entries from reference file
Called by other functions
Args: $pSolutionNode # the Dock solution to replace in file
Return: # of Device entries removed
#################################################################################>
Function Remove_XMLDevices {
[CmdletBinding()] param( $pSolutionNode )
if ( $Script:DebugInfo ) { ">> Remove_XMLDevices() - Solution: $($pSolutionNode.Name)" | out-file -append $Script:LogFilePath }
$rx_RemovedCount = 0
$rx_XMLDevices = $Script:xmlContent.SelectNodes("ImagePal/Devices/Device")
$rx_DevNodes = $rx_XMLDevices | Where-Object { $_.Solutions.UpdateInfo.IdRef -eq $pSolutionNode.Id }
foreach ( $i_DevNode in [array]$rx_DevNodes ) {
$rx_DevIDRemoved = $i_DevNode.DeviceID
$i_DevNode.ParentNode.RemoveChild($i_DevNode) | Out-Null
if ( $Script:DebugInfo ) { ".. Remove_XMLDevices() removed Dev entry: $rx_DevIDRemoved" | out-file -append $Script:LogFilePath }
$rx_RemovedCount += 1
}
if ( $Script:DebugInfo ) { "<< Remove_XMLDevices() - removed: $rx_RemovedCount" | out-file -append $Script:LogFilePath }
return $rx_RemovedCount
} # Function Remove_XMLDevices
<#################################################################################
Function Remove_XMLSoftwareInstalled
Handle specifics of removing a category Software softpaq, which may have
entries in InstalledSoftware, UWP, and Devices sections of the ref file
Args: $pSolutionNode # the Software solution to replace in file
Return: $true if update occurred
#################################################################################>
Function Remove_XMLSoftwareInstalled {
[CmdletBinding()] param( $pSolutionNode )
if ( $Script:DebugInfo ) { ">> Remove_XMLSoftwareInstalled() - Solution: $($pSolutionNode.Name)" | out-file -append $Script:LogFilePath }
$rx_RemovedSoftwareInstalled = $false
# remove entries from SoftwareInstalled area
$rx_XMLSoftwareInstalled = $Script:xmlContent.SelectNodes("ImagePal/SystemInfo/SoftwareInstalled/Software")
$rx_SWNode = $rx_XMLSoftwareInstalled | Where-Object { $_.Solutions.UpdateInfo.IdRef -eq $pSolutionNode.Id }
if ( $rx_SWNode ) {
$rx_SWInstalled = $rx_SWNode.Name
$rx_SWNode.ParentNode.RemoveChild($rx_SWNode) | Out-Null
if ( $Script:DebugInfo ) { ".. << Remove_XMLSoftwareInstalled() removed: $rx_SWInstalled" | out-file -append $Script:LogFilePath }
$rx_RemovedSoftwareInstalled = $true
}
return $rx_RemovedSoftwareInstalled
} # Function Remove_XMLSoftwareInstalled
<#################################################################################
Function Update_XMLDevices
Searches all /Devices nodes in reference file and replaces the solution ID with a
replacement solution ID, and also updates the driver date and version of the node
Args: $pSolutionNode # XML Solution node to replace in /Devices
$pssSolutionNode # XML node to replace with
Returns: no return
#################################################################################>
Function Update_XMLDevices {
[CmdletBinding()] param( $pSolutionNode, $pssSolutionNode )
if ( $Script:DebugInfo ) { ">> Update_XMLDevices() - Solution: $($pSolutionNode.Name) with $($pssSolutionNode.Name)" | out-file -append $Script:LogFilePath }
$ux_UpdatedDeviceCount = 0
$ux_XMLDevices = $Script:xmlContent.SelectNodes("ImagePal/Devices/Device")
foreach ( $i_DevNode in $ux_XMLDevices ) {
if ( $i_DevNode.Solutions.UpdateInfo.IDRef -eq $pSolutionNode.Id ) {
$i_DevNode.Solutions.UpdateInfo.IDRef = $pssSolutionNode.id
$i_DevNode.DriverVersion = $pssSolutionNode.Version
# compute Devices format of Date (backwards from Softpaq ReleaseDate)
# NOTE: use Softpaq Release Date, since is all we have in reference file
# NOTE: use Softpaq Release Date, since is all we have in reference file
$ux_ssDate = $pssSolutionNode.DateReleased.split('-') # 2023-03-13 - /Solutions
$i_DevNode.DriverDate = $ux_ssDate[1]+'/'+$ux_ssDate[2]+'/'+$ux_ssDate[0] # 03/28/2023 - /Devices
if ( $Script:DebugInfo ) { ".. Update_XMLDevices() updated DevID: $($i_DevNode.DeviceID)" | out-file -append $Script:LogFilePath }
$ux_UpdatedDeviceCount += 1
} # if ( $rx_DevSolution -eq $pSolutionNode.Id )
} # foreach ( $iDev in $ux_XMLDevices )
return $ux_UpdatedDeviceCount
} # Function Update_XMLDevices
<#################################################################################
Function Update_XMLSoftwareInstalled
Searches node in reference file and replaces the solution ID with a
replacement solution ID, and also updates the driver date and version of the node
Args: $pSolutionNode # XML Solution node to replace in /Devices
$pssSolutionNode # XML node to replace with
Returns: $true if update happened
#################################################################################>
Function Update_XMLSoftwareInstalled {
[CmdletBinding()] param( $pSolutionNode, $pssSolutionNode )
if ( $Script:DebugInfo ) { ">> Update_XMLSoftwareInstalled() - Solution: $($pSolutionNode.Name) with $($pssSolutionNode.Name)" | out-file -append $Script:LogFilePath }
$ux_UpdatedSoftwareInstalled = $false
# Check for the SoftwareInstalled area of the Reference File
$ux_XMLSoftwareInstalled = $Script:xmlContent.SelectNodes("ImagePal/SystemInfo/SoftwareInstalled/Software")
$ux_SWNode = $ux_XMLSoftwareInstalled | Where-Object { $_.Solutions.UpdateInfo.IdRef -eq $pSolutionNode.Id }
if ( $ux_SWNode ) {
$ux_SWNode.Solutions.UpdateInfo.IdRef = $pssSolutionNode.Id
$ux_SWNode.Version = $pssSolutionNode.Version
# DateReleased 2023-01-09 >> InstalledDate 20230410
$ux_SWNode.InstalledDate = $pssSolutionNode.DateReleased.Replace('-','')
$ux_UpdatedSoftwareInstalled = $true
if ( $Script:DebugInfo ) { ".. << Update_XMLSoftwareInstalled() updated: $($ux_SWNode.Name)" | out-file -append $Script:LogFilePath }
} # if ( $ux_SWNode )
return $ux_UpdatedSoftwareInstalled
} # Update_XMLSoftwareInstalled
<#################################################################################
Function Update_XMLUWPApp
This function finds entries in the reference file UWP entry matching a UWP
app from the CVA file associtated with the replacement Softpaq solution and
updates the reference file entry with the UWP app info from [Store Package Info]
Args: $pSolutionNode # the solution XML node to replace in file
$pssSolutionNode # the replacement solution softpaq node
$pSpqMetadata
Return: count of UWP entries updated
#################################################################################>
Function Update_XMLUWPApp {
[CmdletBinding()] param( $pSolutionNode, $pssSolutionNode, $pSpqMetadata )
if ( $Script:DebugInfo ) { ">> Update_XMLUWPApp() - Solution: $($pSolutionNode.Name) with $($pssSolutionNode.Name)" | out-file -append $Script:LogFilePath }
$ux_UpdateCount = 0
$ux_XMLUWPInstalled = $Script:xmlContent.SelectNodes("ImagePal/SystemInfo/UWPApps/UWPApp")
$ux_UWPNode = $ux_XMLUWPInstalled | Where-Object { $_.Solutions.UpdateInfo.IdRef -eq $pSolutionNode.Id }
foreach ( $i_UWPNode in [array]$ux_UWPNode ) {
$i_UWPNode.Solutions.UpdateInfo.IdRef = $pssSolutionNode.Id
# check for the superseded Softpaqs UWP component, by name, to obtain version info
# return $gu_CVAUWPFullName [0], $gu_CVAUWPVersion [1]
$ux_ssUWPRet = Get_UWPInfo $pSpqMetadata $i_UWPNode.Name
if ( $ux_ssUWPRet[1] ) {
if ( $Script:DebugInfo ) {
"Update_XMLUWPApp() UWP found in CVA (full name): $($ux_ssUWPRet[0])" | out-file -append $Script:LogFilePath
"Update_XMLUWPApp() UWP found in ref file (full name): $($i_UWPNode.FullName)" | out-file -append $Script:LogFilePath
}
if ( $i_UWPNode.FullName -match '_x64_' ) {
# AppUp.IntelGraphicsExperience_1.100.4628.0_x64__8j3eq9eme6ctt # reference UWPApp file entry
# AppUp.IntelGraphicsExperience_1.100.4478.0_neutral_~_8j3eq9eme6ctt # CVA file store entry
$i_UWPNode.FullName = [string]$ux_ssUWPRet[0].Replace('_neutral_`~_','_x64_')
} else {
$i_UWPNode.FullName = [string]$ux_ssUWPRet[0].replace('_`~_','__')
}
$i_UWPNode.Version = $ux_ssUWPRet[1] # use version from superseded CVA store entry
} else {
$i_UWPNode.Version = $pssSolutionNode.Version # use superseded Softpaq file version
}
$ux_UpdateCount += 1
} # foreach ( $i_UWPNode in [array]$ux_UWPNode )
if ( $Script:DebugInfo ) { "<< Update_XMLUWPApp() update UWP count:$($ux_UpdateCount)" | out-file -append $Script:LogFilePath }
return $ux_UpdateCount
} # Function Update_XMLUWPApp
<#################################################################################
Function Remove_Solution
Here we remove the node for any solution selected in the UI list
If more than one item is selected, all are removed
For each category, we separatly remove any items in the reference file that
point to the solution
Args: $pFormSolutionsList # Solutions node list from XML reference file
$pCategories # list of categories to display in form
Return: count of displayed items in Solutions list box
#################################################################################>
Function Remove_Solution {
[CmdletBinding()] param( $pFormSolutionsList, $pCategories, $pName2match )
if ( $Script:DebugInfo ) { ">> Remove_Solution()" | out-file -append $Script:LogFilePath }
$rs_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
# here we will remove any selected node in the Softpaq list
foreach ( $i_Sol in $pFormSolutionsList.SelectedItems ) {
# find the selected Softpaq node in /Solutions
$rs_SoftpaqID = $i_Sol.split(' ')[0] # get the SoftPaq ID from string
$rs_Node = $rs_XMLSolutions | Where-Object { $_.id -eq $rs_SoftpaqID }
# handle BIOS separate from other categories
if ( $rs_Node.Category -match 'BIOS' ) {
$rs_Removed = $false # do NOT remove BIOS Softpaq entry from /Solutions
} else {
$rx_DockCheck = $false
switch -regex ( $rs_Node.Category ) {
'^Driver*' {
$rx_UWPcount = Remove_XMLUWPApps $rs_Node
$rx_Devcount = Remove_XMLDevices $rs_Node
if ( ($rx_UWPcount -gt 0) -or ($rx_Devcount -gt 0)) { $rs_Removed = $true }
}
'^Software*' {
$rx_SWInstRemoved = Remove_XMLSoftwareInstalled $rs_Node
$rx_UWPcount = Remove_XMLUWPApps $rs_Node
$rx_Devcount = Remove_XMLDevices $rs_Node
if ( $rx_UWPcount -or ($rx_UWPcount -gt 0) -or ($rx_Devcount -gt 0)) { $rs_Removed = $true }
}
'^Dock*' {
$rx_DockCheck = $true
$rs_Removed = Remove_XMLDevices $rs_Node # remove devices entries first
}
'firmware*' {
if ( -not $rx_DockCheck ) {
$rs_Removed = Remove_XMLDevices $rs_Node
}
}
} # switch -regex ( $rs_Node.Category )
$rs_Node.ParentNode.RemoveChild($rs_Node) | Out-Null # remove the Solutions entry
$rs_Removed = $true
} # else if ( $rs_Node.Category -match 'BIOS' )
} # foreach ( $i_Sol in $pFormSolutionsList.SelectedItems )
if ( $rs_Removed ) {
$Script:xmlContent.Save((Convert-Path $Script:RefFilePath))
$rs_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
$rs_SpqCount = Show_SoftpaqList $pFormSolutionsList $rs_XMLSolutions $pCategories $pName2match
}
if ( $Script:DebugInfo ) { "<< Remove_Solution()" | out-file -append $Script:LogFilePath }
return $rs_Removed
} # Function Remove_Solution
<#################################################################################
Function Replace_Solution
Here we replace a Softpaq solution with a superseded entry
otherwise, we replace the solution with the replacement in the list
Args: $pFormSolutionsList # Solutions node list from XML reference file
$pSolution # solution/Softpaq to remove or replace (if !$null)
$pssSolution # solution/Softpaq to replace with (if !$null)
$pCategories # list of categories to display in form
Return: count of displayed items in Solutions list box
#################################################################################>
Function Replace_Solution {
[CmdletBinding()] param( $pFormSolutionsList, $pSolution, $pssSolution, $pCategories, $pName2match )
if ( $Script:DebugInfo ) { ">> Replace_Solution() - Solution: $($pSolution.split(' ')[0]) with $($pssSolution.split(' ')[0])" | out-file -append $Script:LogFilePath }
$rs_SoftpaqReplaced = $false
$rs_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
$rs_ssXMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions-Superseded/UpdateInfo")
# let's see if this is a replace order (ss arg must !$null)
if ( $pssSolution.length -gt 0 ) {
# find the category for the softpaq
foreach ( $iSolution in $rs_XMLSolutions ) {
if ( $iSolution.Id -eq $pSolution.split(' ')[0] ) { $rs_SolutionCategory = $iSolution.Category ; break }
}
$rs_SolutionID = $pSolution.split(' ')[0] # get the Softpaq ID from entry string
$rs_RplSolutionID = $pssSolution.split(' ')[0]
$rs_Node = $rs_XMLSolutions | Where-Object { $_.id -eq $rs_SolutionID }
$rs_ssNode = $rs_ssXMLSolutions | Where-Object { $_.id -eq $rs_RplSolutionID } # find the superseding node
if ( $rs_SolutionCategory -match "^bios*" ) {
$rs_ssBIOSStringList = $pssSolution.split('/').Trim()
$rs_BIOSVerString = $pssSolution.split('\(')[1].Substring(0,3)+' Ver. '+$rs_ssBIOSStringList[1]
$rs_BIOSDate = $rs_ssBIOSStringList[2].split('-')
$rs_BIOSDate = $rs_BIOSDate[1]+'/'+$rs_BIOSDate[2]+'/'+$rs_BIOSDate[0]
$Script:xmlContent.ImagePal.SystemInfo.System.BiosVersion2 = $rs_BIOSVerString
$Script:xmlContent.ImagePal.SystemInfo.System.BiosDate = $rs_BIOSDate
$Script:xmlContent.ImagePal.SystemInfo.System.Solutions.UpdateInfo.IdRef = $rs_RplSolutionID
$rs_SoftpaqReplaced = $true
} else {
# we need to handle UWP apps versions, so let's find out the supersed Softpaq UWP's
# by retrieving the CVA file contents for the Store Apps section list
Try {
$Error.Clear()
$rs_lineNum = ((get-pscallstack)[0].Location -split " line ")[1] # get code line # in case of failure
$rs_spqMetadata = Get-SoftpaqMetadata $rs_RplSolutionID -ErrorAction Stop # get CVA file for this Softpaq
} catch {
$rs_Err = $error[0].exception # OPTIONAL: $error[0].exception.gettype().fullname
write-host "$($rs_RplSolutionID): Get-SoftpaqMetadata exception: on line number $($rs_lineNum) - $($rs_Err)"
return $False
} # catch
$rx_DockCheck = $false
switch -regex ( $rs_SolutionCategory ) {
'^Driver*' {
$rx_DevCount = Update_XMLDevices $rs_Node $rs_ssNode
$rx_UWPCount = Update_XMLUWPApp $rs_Node $rs_ssNode $rs_spqMetadata
}
'^Software*' {
$rs_SoftpaqReplaced = Update_XMLSoftwareInstalled $rs_Node $rs_ssNode
$rx_UWPCount = Update_XMLUWPApp $rs_Node $rs_ssNode $rs_spqMetadata
$rx_devCount = Update_XMLDevices $rs_Node $rs_ssNode
}
'^Dock*' {
$rx_DockCheck = $true
$rx_UWPCount = Update_XMLUWPApp $rs_Node $rs_ssNode $rs_spqMetadata
$rx_DevCount = Update_XMLDevices $rs_Node $rs_ssNode
}
'firmware' {
if ( -not $rx_DockCheck ) {
$rs_SoftpaqReplaced = Update_XMLDevices $rs_Node $rs_ssNode
}
}
} # switch -regex ( $rs_SolutionCategory )
} # else if ( $rs_SolutionCategory -match "^bios*" )
# finally replace the current Softpaq with the chosen Softpaq in file
$rs_Node.ParentNode.InsertAfter($rs_ssNode,$rs_Node) # and add it to the list
$rs_Node.ParentNode.RemoveChild($rs_Node) | Out-Null # then remove the other one
} # if ( $pssSolution.length -gt 0 )
$Script:xmlContent.Save((Convert-Path $Script:RefFilePath))
$rs_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
$rs_SpqCount = Show_SoftpaqList $pFormSolutionsList $rs_XMLSolutions $pCategories $pName2match
if ( $Script:DebugInfo ) { ">> Replace_Solution()" | out-file -append $Script:LogFilePath }
return $rs_SoftpaqReplaced
} # Function Replace_Solution
<#################################################################################
Function Show_ContextFileMenu
displays CVA or Release Notes (html) file based on context menu click
Args: $pSolution # solution/Softpaq to remove or replace (if !$null)
$pFileType # 'cva'|'html'
$pWhichNode # $true to look in /Solutions, $false to look in superseded
Return: count of displayed items in Solutions list box
#################################################################################>
Function Show_ContextFileMenu {
[CmdletBinding()] param( $pSolution, $pFileType, $pWhichNode )
if ( $pWhichNode ) { # $true means /Solutions
$sc_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
} else { # $false means /superseded-Solutions
$sc_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions-Superseded/UpdateInfo")
}
<# /Solutions entries in reference file contain:
<Url>ftp.hp.com/pub/softpaq/sp147501-148000/sp147684.exe</Url>
<ReleaseNotesUrl>ftp.hp.com/pub/softpaq/sp147501-148000/sp147684.html</ReleaseNotesUrl>
<CvaUrl>ftp.hp.com/pub/softpaq/sp147501-148000/sp147684.cva</CvaUrl>
#>
foreach ( $iSoftpaq in $sc_XMLSolutions ) {
if ( $iSoftpaq.Id -like $pSolution ) {
switch ( $pFileType ) {
'cva' { $url = $($iSoftpaq.CvaUrl) ;
$sc_file2open = "$($iSoftpaq.Id).cva" ;
Invoke-WebRequest $url -OutFile ".\$(Split-Path -Leaf $url)"
Start-Process ".\\$sc_file2open"
}
'html' { $url = $($iSoftpaq.ReleaseNotesUrl) ;
$sc_currLoc = get-location
Invoke-WebRequest $url -OutFile ".\$(Split-Path -Leaf $url)"
$sc_file2open = "$($iSoftpaq.Id).html"
$sc_fullpath = $sc_currLoc.Path.replace('\','/')+'/'+$sc_file2open
Start-Process file:'//'$sc_fullpath
}
} # switch ( $pFileType )
break
} # if ( $iSoftpaq.Id -like $pSolution )
} # foreach ( $iSoftpaq in $sc_XMLSolutions )
} # Function Show_ContextFileMenu
<#################################################################################
Function Init_Repo
initializes a HPIA repository
Args: $pStartLoc # initial location to search for a repo folder
Return: selected repository folder
#################################################################################>
Function Init_Repo {
[CmdletBinding()] param( $pStartLoc )
$ir_Return = @{} # function returns 2 items in array
$ir_Return.Folder = ""
$ir_Return.Message = "Repository Folder not Selected"
$ir_foldername = New-Object System.Windows.Forms.FolderBrowserDialog
$ir_foldername.Description = "Select a Repository folder"
$ir_foldername.SelectedPath = $pStartLoc
if( $ir_foldername.ShowDialog() -eq "OK" ) {
$ir_Return.Folder = $ir_foldername.SelectedPath
$ir_CurrLocSaved = Get-location
Try {
$Error.Clear()
set-location $ir_Return.Folder
# is this already a valid repository?
$ir_repositoryInfo = Get-RepositoryInfo -EA SilentlyContinue
$ir_FilterMsg = "$($ir_Return.Folder) is already a repository. Is it OK to clear existing filters?"
$ir_askOKCancel = [System.Windows.Forms.MessageBox]::Show($ir_FilterMsg,'Asterisk','OKCancel','Asterisk')
if ( $ir_askOKCancel -eq 'Ok' ) {
$ir_RepoFilters = (Get-RepositoryInfo).Filters
foreach ( $ir_Platform in $ir_RepoFilters.platform) {
Remove-RepositoryFilter -platform $ir_Platform -yes 6>&1
}
$ir_Return.Message = 'Existing Repository. Cleared current filters'
if ( $Script:DebugInfo ) { 'Existing Repository. Cleared current filters' | out-file -append $Script:LogFilePath }
# next remove traces of previous 'sync's
$ir_repoCacheFolder = "$($ir_Return.Folder)\.repository\cache"
if ( Test-Path $ir_repoCacheFolder) {
Remove-Item -Path "$($ir_repoCacheFolder)" -Recurse -Force
if ( $Script:DebugInfo ) { '... and existing cached files' | out-file -append $Script:LogFilePath }
}
} else {
$ir_Return.Message = 'Existing Repository. Filters not cleared'
} # if ( $ir_askOKCancel -eq 'Ok' )
} Catch {
write-host $error[0].exception
Initialize-Repository
# configuring the repo for HPIA's use
Set-RepositoryConfiguration -setting OfflineCacheMode -cachevalue Enable 6>&1
# configuring to create 'Contents.CSV' after every Sync -- NOTE: we won't do syncs here
Set-RepositoryConfiguration -setting RepositoryReport -Format csv 6>&1
$ir_Return.Message = 'Repository created and initialized'
} # Try Catch
set-location $ir_CurrLocSaved
} # if( $ir_foldername.ShowDialog() -eq "OK" )
return $ir_Return
} # Function Init_Repo
<#################################################################################
Function FindPlatform_GUI
Here we ask the user to select a new device and return the name (and SysID)
#################################################################################>
Function FindPlatform_GUI {
$fp_FormWidth = 400
$fp_FormHeigth = 400
$fp_Offset = 20
$fp_FieldHeight = 20
$fp_PathFieldLength = 200
$fp_EntryForm = New-Object System.Windows.Forms.Form
$fp_EntryForm.MaximizeBox = $False ; $fp_EntryForm.MinimizeBox = $False #; $fp_EntryForm.ControlBox = $False
$fp_EntryForm.Text = "Search for Device to Manage"
$fp_EntryForm.Width = $fp_FormWidth ; $fp_EntryForm.height = 400 ; $fp_EntryForm.Autosize = $true
$fp_EntryForm.StartPosition = 'CenterScreen'
$fp_EntryForm.Topmost = $true
$fp_EntryForm.Add_KeyDown({
if ($_.KeyCode -eq "Escape") { # if escape, exit
$fp_EntryForm.Close()
}
})
# ------------------------------------------------------------------------
# find and add model entry
$fp_EntryId = New-Object System.Windows.Forms.Label
$fp_EntryId.Text = "System"
$fp_EntryId.location = New-Object System.Drawing.Point($fp_Offset,$fp_Offset) # (from left, from top)
$fp_EntryId.Size = New-Object System.Drawing.Size(60,20) # (width, height)
$fp_EntryModel = New-Object System.Windows.Forms.TextBox
$fp_EntryModel.Text = ""
$fp_EntryModel.Multiline = $false
$fp_EntryModel.location = New-Object System.Drawing.Point(($fp_Offset+70),($fp_Offset-4)) # (from left, from top)
$fp_EntryModel.Size = New-Object System.Drawing.Size($fp_PathFieldLength,$fp_FieldHeight)# (width, height)
$fp_EntryModel.ReadOnly = $False
$fp_EntryModel.Name = "Model Name"
$fp_EntryModel.add_MouseHover($ShowHelp)
$fp_EntryModel.Add_KeyDown({
if ($_.KeyCode -eq "Enter") {
$fp_SearchGo.PerformClick()
}
})
# add 'wait...' message label
$fp_Entrymsg = New-Object System.Windows.Forms.Label
$fp_Entrymsg.ForeColor = 'blue'
$fp_Entrymsg.location = New-Object System.Drawing.Point($fp_Offset,($fp_Offset+20)) # (from left, from top)
$fp_Entrymsg.Size = New-Object System.Drawing.Size(160,40) # (width, height)
$fp_Entrymsg.Text = 'Use [Search] to find platform, or [Load] to use saved file'
# add 'search' button
$fp_SearchGo = New-Object System.Windows.Forms.Button
$fp_SearchGo.Location = New-Object System.Drawing.Point(($fp_PathFieldLength+$fp_Offset+80),($fp_Offset-6))
$fp_SearchGo.Size = New-Object System.Drawing.Size(75,23)
$fp_SearchGo.Text = 'Search'
$fp_SearchGo.Add_Click( {
if ( $fp_EntryModel.Text ) {
$fp_AddEntryList.Items.Clear()
$fp_Entrymsg.Text = "Retrieving Reference File... Please, wait"
$lModels = Get-HPDeviceDetails -Like -Name $fp_EntryModel.Text # find all models matching entered text
if ( $lModels.count -eq 0 ) {
$fp_Entrymsg.Text = 'No matching platforms found'
} else {
# add models to the list
foreach ( $iModel in ($lModels | sort-Object -Property Name) ) {
[void]$fp_AddEntryList.Items.Add($iModel.SystemID+':'+$iModel.Name)
}
$fp_Entrymsg.Text = ''
}
$fp_EntryForm.AcceptButton = $fp_okButton
} # if ( $fp_EntryModel.Text )
} )
# add 'models list' list box
$fp_AddEntryList = New-Object System.Windows.Forms.ListBox
$fp_AddEntryList.Name = 'Entries'
$fp_AddEntryList.Autosize = $false
$fp_AddEntryList.location = New-Object System.Drawing.Point($fp_Offset,80) # (from left, from top)
$fp_AddEntryList.Size = New-Object System.Drawing.Size(($fp_FormWidth-80),($fp_FormHeigth/2)) # (width, height)
$fp_AddEntryList.add_click( { $fp_okButton.Enabled = $true })
$fp_AddEntryList.add_doubleClick( { $fp_okButton.PerformClick() } )
# ------------------------------------------------------------------------
#$fp_FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ InitialDirectory = [Environment]::GetFolderPath('Desktop') }
$fp_FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ InitialDirectory = $Script:CacheDir }
#$fp_FileBrowser.InitialDirectory = $v_HPIAPath
$fp_FileBrowser.Title = "Locate XML reference file"
$fp_FileBrowser.Filter = "xml file | *.xml"
$fp_LoadFile = New-Object System.Windows.Forms.Button
$fp_LoadFile.Location = New-Object System.Drawing.Point(($fp_Offset),($fp_FormHeigth-80))
$fp_LoadFile.Size = New-Object System.Drawing.Size(75,23)
$fp_LoadFile.Text = 'Load File'
$fp_LoadFile.Add_Click( {
$fp_FileBrowse = $fp_FileBrowser.ShowDialog()
if ( $fp_FileBrowse -eq 'OK' ) {
$fp_filePath = $fp_FileBrowser.FileName
[void]$fp_AddEntryList.Items.Add($fp_filePath)
$fp_AddEntryList.SelectedIndex = 0
$fp_okButton.Enabled = $true
$fp_okButton.PerformClick()
}
} )
# ------------------------------------------------------------------------
# show the dialog, and once user preses OK, add the model and create the flag file for addons
$fp_okButton = New-Object System.Windows.Forms.Button
$fp_okButton.Location = New-Object System.Drawing.Point(($fp_FormWidth-120),($fp_FormHeigth-80))
$fp_okButton.Size = New-Object System.Drawing.Size(75,23)
$fp_okButton.Text = 'OK'
$fp_okButton.Enabled = $False
$fp_okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$fp_cancelButton = New-Object System.Windows.Forms.Button
$fp_cancelButton.Location = New-Object System.Drawing.Point(($fp_FormWidth-200),($fp_FormHeigth-80))
$fp_cancelButton.Size = New-Object System.Drawing.Size(75,23)
$fp_cancelButton.Text = 'Cancel'
$fp_cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::CANCEL
$fp_EntryForm.AcceptButton = $fp_SearchGo # enable 'Enter' at the platform name field
$fp_EntryForm.CancelButton = $fp_cancelButton
$fp_EntryForm.Controls.AddRange(@($fp_EntryId,$fp_EntryModel,$fp_Entrymsg,$fp_SearchGo))
$fp_EntryForm.Controls.AddRange(@($fp_AddEntryList,$fp_LoadFile,$fp_cancelButton, $fp_okButton))
$fp_Result = $fp_EntryForm.ShowDialog()
if ($fp_Result -eq [System.Windows.Forms.DialogResult]::OK) {
return $fp_AddEntryList.SelectedItem
}
} # Function FindPlatform_GUI
<#################################################################################
Function Create_Form
this is the core of the script
#################################################################################>
Function Create_Form {
Add-Type -AssemblyName PresentationFramework
Add-Type -assembly System.Windows.Forms
$FormWidth = 800
$FormHeight = 640
$LeftOffset = 20
$TopOffset = 20
#----------------------------------------------------------------------------------
# Create container form
$cf_Form = New-Object System.Windows.Forms.Form
$cf_Form.Text = "Reference File editor - "+$ReFileVersion # shows on the header
$cf_Form.Name = 'MyForm' # this is how the form can be addressed by code
$cf_Form.Width = $FormWidth
$cf_Form.height = $FormHeight
$cf_Form.Autosize = $false # ... try setting to $true
$cf_Form.StartPosition = 'CenterScreen' # ... Options: CenterParent, CenterScreen, Manual (use Location property),
#----------------------------------------------------------------------------------
# Add 'OS' label
$cf_OSLabel = New-Object System.Windows.Forms.Label
$cf_OSLabel.Text = "OS"
$cf_OSLabel.location = New-Object System.Drawing.Point($LeftOffset,$TopOffset) # (from left, from top)
$cf_OSLabel.Size = New-Object System.Drawing.Size(40,20) # (width, height)
$cf_OSLabel.TextAlign = "BottomCenter"
<# BottomCenter,BottomLeft,BottomRight,MiddleCenter,MiddleLeft,MiddleRight,TopCenter,TopLeft,TopRight #>
#----------------------------------------------------------------------------------
# Add 'OS' data field
$cf_OSList = New-Object System.Windows.Forms.ComboBox
$cf_OSList.Size = New-Object System.Drawing.Size(60,20) # (width, height)
$cf_OSList.Location = New-Object System.Drawing.Point(($LeftOffset+50), ($TopOffset+4))
$cf_OSList.DropDownStyle = "DropDownList"
$cf_OSList.Name = "OSList"
[void]$cf_OSList.Items.AddRange($Script:OSs)
$cf_OSList.SelectedItem = $Script:OSs[0]
$cf_OSList.Add_SelectedIndexChanged( {
$cf_OSVerList.Items.Clear()
switch ( $cf_OSList.Text ) {
'10' {
[void]$cf_OSVerList.Items.AddRange($Script:OS10Vers)
$cf_OSVerList.SelectedItem = $Script:OS10Vers[3] # set visible default entry
}
'11' {
[void]$cf_OSVerList.Items.AddRange($Script:OS11Vers)
$cf_OSVerList.SelectedItem = $Script:OS11Vers[1] # set visible default entry
}
}
}) # $cf_OSList.Add_SelectedIndexChanged
#----------------------------------------------------------------------------------
# Add 'OS Version' label
$cf_OSVerLabel = New-Object System.Windows.Forms.Label
$cf_OSVerLabel.Text = "Version"
$cf_OSVerLabel.location = New-Object System.Drawing.Point(($LeftOffset+110),$TopOffset) # (from left, from top)
$cf_OSVerLabel.Size = New-Object System.Drawing.Size(60,20) # (width, height)
$cf_OSVerLabel.TextAlign = "BottomCenter"
# Add 'OS Version' data field
$cf_OSVerList = New-Object System.Windows.Forms.ComboBox
$cf_OSVerList.Size = New-Object System.Drawing.Size(60,20) # (width, height)
$cf_OSVerList.Location = New-Object System.Drawing.Point(($LeftOffset+170), ($TopOffset+4))
$cf_OSVerList.DropDownStyle = "DropDownList"
$cf_OSVerList.Name = "Version"
[void]$cf_OSVerList.Items.AddRange($Script:OS10Vers)
$cf_OSVerList.SelectedItem = $Script:OS10Vers[3] # set visible default entry
# Add 'Windows' label
$cf_Message = New-Object System.Windows.Forms.Label
$cf_Message.location = New-Object System.Drawing.Point($LeftOffset,($TopOffset+30)) # (from left, from top)
$cf_Message.Size = New-Object System.Drawing.Size(240,20) # (width, height)
$cf_Message.Name = 'Message'
$cf_Message.ForeColor = 'blue'
$cf_Message.Text = "Confirm OS and OS Version"
$cf_Message.BorderStyle = 'none'
$cf_Form.Controls.AddRange(@($cf_OSLabel,$cf_OSList,$cf_OSVerLabel,$cf_OSVerList,$cf_Message))
#----------------------------------------------------------------------------------
# Add platform Select Button
$cf_SearchButton = New-Object System.Windows.Forms.Button
$cf_SearchButton.Text = "Select Platform"
$cf_SearchButton.location = New-Object System.Drawing.Point(($LeftOffset+280),$TopOffset) # (from left, from top)
$cf_SearchButton.AutoSize = $true
$cf_SearchButton.TextAlign = "MiddleRight"
$cf_SearchButton.add_click( {
$cf_PlatformReturn = FindPlatform_GUI #returns platform id:name or xml reference file
if ( $null -ne $cf_PlatformReturn ) {
$cf_RefFileMsg.Text = "... Please, Wait"
if ( $cf_PlatformReturn -match "xml$") { # NEW: if return is an XML file, we'll work on that instead
$cf_RefFileSelected = Get_LocalFile $cf_PlatformReturn
$cf_Msg = "Reference File selected (.bak made)"
$Script:RefFilePath = $cf_PlatformReturn
# compile platform Text file <SysID:Model name> for field display
$cf_PlatformFileName = [System.IO.Path]::GetFileNameWithoutExtension($cf_PlatformReturn)
$cf_PlatformID = $cf_PlatformFileName.Substring(0,4)
$cf_PlatformName = ([array](Get-HPDeviceDetails -platform $cf_PlatformID)[0]).Name
$cf_SelectedPlatform.Text = $cf_PlatformID+':'+$cf_PlatformName
} else {
$cf_SelectedPlatform.Text = $cf_PlatformReturn
$Script:OS = 'Win'+$cf_OSList.SelectedItem # make it 'win10', 'win11' as req'd by CMSL cmds
$Script:OSVer = $cf_OSVerList.SelectedItem
$PlatformID = $cf_SelectedPlatform.Text.substring(0,4)
$Script:RefFilePath = Get_FileFromHP $PlatformID $Script:OS $Script:OSVer
$cf_Msg = "Reference File is a working copy"
} # else if ( $cf_PlatformReturn -match "xml$")
# Do an initial load of the Softpaqs from the selected Reference File
if ( $Script:RefFilePath ) {
$cf_RefFileMsg.Text = $cf_Msg
$cf_RefFilePath.Text = $Script:RefFilePath
$cf_RefFilePath.Select($cf_RefFilePath.Text.Length, 0) # show end of path
$cf_RefFilePath.ScrollToCaret()
$Script:xmlContent = [xml](Get-Content -Path $Script:RefFilePath)
$cf_XMLSolutions = $Script:xmlContent.SelectNodes("ImagePal/Solutions/UpdateInfo")
$cf_Categories = @() # no categories selected to start with
$cf_SpqCount = Show_SoftpaqList $cf_SoftpaqsList $cf_XMLSolutions $cf_Categories $cf_SolutionSearch.Text $null
$cf_CurrentSpqsMsg.Text = "ctl-Click for multi-select ($($cf_SpqCount))"
$cf_CategoryBIOS.Checked = $false ; $cf_CategoryBIOS.Enabled = $true
$cf_CategoryDriver.Checked = $false ; $cf_CategoryDriver.Enabled = $true
$cf_TypeNetwork.Checked = $false ; $cf_TypeNetwork.Enabled = $false
$cf_TypeGraphics.Checked = $false ; $cf_TypeGraphics.Enabled = $false
$cf_TypeStorage.Checked = $false ; $cf_TypeStorage.Enabled = $false
$cf_TypeAudio.Checked = $false ; $cf_TypeAudio.Enabled = $false
$cf_TypeChipset.Checked = $false ; $cf_TypeChipset.Enabled = $false
$cf_CategorySoftware.Checked = $false ; $cf_CategorySoftware.Enabled = $true
$cf_CategoryFirmware.Checked = $false ; $cf_CategoryFirmware.Enabled = $true
$cf_CategoryDock.Checked = $false ; $cf_CategoryDock.Enabled = $true
$cf_SolutionSearch.Enabled = $true # enable solution search field
$cf_SolutionGo.Enabled = $true # enable solution search 'Go' button
} else {
$cf_RefFileMsg.Text = 'Error 404: Reference File not found'
$cf_CurrentSpqsMsg.Text = ""
} # else if ( $Script:RefFilePath )
} # if ( $null -ne $cf_PlatformReturn )
$cf_actionMsg.Text = "" # in case we start a new file edit and a there is a leftover msg
} ) # $cf_SearchButton.add_click
# Add 'selected platform' data field
$cf_SelectedPlatform = New-Object System.Windows.Forms.TextBox
$cf_SelectedPlatform.location = New-Object System.Drawing.Point(($LeftOffset+390),($TopOffset+2)) # (from left, from top)
$cf_SelectedPlatform.Size = New-Object System.Drawing.Size(300,20) # (width, height)
$cf_SelectedPlatform.BorderStyle = 'Fixed3D' # Options: Fixed3D, FixedSingle, None (default)
$cf_SelectedPlatform.Text = 'Platform not selected...'
$cf_SelectedPlatform.ReadOnly = $true
$cf_Form.Controls.AddRange(@($cf_SearchButton,$cf_SelectedPlatform))
###################################################################################
# create group box to hold all Softpaq data stuff
###################################################################################
$SolutionGroupBox = New-Object System.Windows.Forms.GroupBox
$SolutionGroupBox.location = New-Object System.Drawing.Point(($LeftOffset),($TopOffset+50)) # (from left, from top)
$SolutionGroupBox.Size = New-Object System.Drawing.Size(700,360) # (width, height)
#----------------------------------------------------------------------------------