-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcheck_requisites.ps1
More file actions
1212 lines (1085 loc) · 45.6 KB
/
check_requisites.ps1
File metadata and controls
1212 lines (1085 loc) · 45.6 KB
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
## Check pre-requisites
# Definition of the requisities and locations
####################################################################################
# NODE #
####################################################################################
$nodeRequiredVersion = "23.7.0"
####################################################################################
# MICROSOFT VISUAL C++ REDISTRIBUTABLE #
####################################################################################
$VCpRequiredVersion = "14.38.33135.0"
$VcpRegPath = 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64'
$VcpUrl = 'https://aka.ms/vs/17/release/vc_redist.x64.exe'
####################################################################################
# GIT #
####################################################################################
$gitRequiredVersion = "2.44.0"
####################################################################################
# DOT NET #
####################################################################################
$dotNetInstallationScriptLocation = "https://dot.net/v1/dotnet-install.ps1"
$dotNetSDKRequiredVersion = "10.0.100"
$dotNetDesktopRuntimeRequiredVersion = "8.0.22"
####################################################################################
# AX CODE #
####################################################################################
$axCodeRequiredVersion = "1.94.2"
$axCodeDownloadUrl = "https://console.simatic-ax.siemens.io/downloads"
####################################################################################
# APAX AX #
####################################################################################
$apaxRequiredVersion = "4.1.1"
$apaxUrl = "https://console.simatic-ax.siemens.io/"
####################################################################################
# APAX LOGIN INXTON #
####################################################################################
$inxtonRegistryUrl = "https://npm.pkg.github.com/"
$nugetFeedUrl = "https://nuget.pkg.github.com/inxton/index.json"
####################################################################################
# VISUAL STUDIO BUILD TOOLS #
####################################################################################
$vsBuildToolInstallationURL = "https://aka.ms/vs/16/release/vs_buildtools.exe"
$vsBuildToolInstallCommand = ".\vs_buildtools.exe --wait --norestart --nocache --passive --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK --add Microsoft.VisualStudio.Component.Windows10SDK.19041"
$vsBuildToolRequiredVersion = "16.11.36631.11"
$expectedVCToolsInstallDir = "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133"
####################################################################################
# VISUAL STUDIO #
####################################################################################
$visualStudioRequiredVersionRange = "[17.8.0,19.0)";
$vsWhereLocation = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
########################################################################################################################################################################
# VERSION CHECKERS/HELPERS #
####################################################################################
# Function to check if the actual version is equal to required version
function MajorMinorBuildRevisionEqual {
param
(
[Parameter(Mandatory)][string]$Item,
[Parameter(Mandatory)][string]$ActualVersion,
[Parameter(Mandatory)][string]$RequiredVersion,
[switch]$Silent
)
$retval = $false
$Actual = [version]$ActualVersion
$Required = [version]$RequiredVersion
if ($Actual -eq $Required)
{
$retval = $true
if(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) is equal to required ($RequiredVersion)." -ForegroundColor Green
}
}
elseif(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) is different to required ($RequiredVersion)." -ForegroundColor Red
}
return $retval
}
# Function to check if the actual version is equal or higher then required version
function MajorMinorBuildRevisionEqualOrHigher {
param
(
[Parameter(Mandatory)][string]$Item,
[Parameter(Mandatory)][string]$ActualVersion,
[Parameter(Mandatory)][string]$RequiredVersion,
[switch]$Silent
)
$retval = $false
$Actual = [version]$ActualVersion
$Required = [version]$RequiredVersion
if ($Actual -ge $Required)
{
$retval = $true
if(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) is equal or higher then required ($RequiredVersion)." -ForegroundColor Green
}
}
elseif(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) is lower then required ($RequiredVersion)." -ForegroundColor Red
}
return $retval
}
# Function to check if the major and minor version is equal and build and revision version is equal or higher
function MajorMinorEqualBuildRevisionEqualOrHigher {
param
(
[Parameter(Mandatory)][string]$Item,
[Parameter(Mandatory)][string]$ActualVersion,
[Parameter(Mandatory)][string]$RequiredVersion,
[switch]$Silent
)
$retval = $false
$Actual = [version]$ActualVersion
$Required = [version]$RequiredVersion
if ($Actual.Major -eq $Required.Major -and $Actual.Minor -eq $Required.Minor -and $Actual.Build -ge $Required.Build -and $Actual.Revision -ge $Required.Revision )
{
$retval = $true
if(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) fits the required one ($RequiredVersion)." -ForegroundColor Green
}
}
elseif(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) does not fit the required ($RequiredVersion)." -ForegroundColor Red
}
return $retval
}
# Function to check if the major minor and build version is equal and revision version is equal or higher
function MajorMinorBuildEqualRevisionEqualOrHigher {
param
(
[Parameter(Mandatory)][string]$Item,
[Parameter(Mandatory)][string]$ActualVersion,
[Parameter(Mandatory)][string]$RequiredVersion,
[switch]$Silent
)
$retval = $false
$Actual = [version]$ActualVersion
$Required = [version]$RequiredVersion
if ($Actual.Major -eq $Required.Major -and $Actual.Minor -eq $Required.Minor -and $Actual.Build -eq $Required.Build -and $Actual.Revision -ge $Required.Revision )
{
$retval = $true
if(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) fits the required one ($RequiredVersion)." -ForegroundColor Green
}
}
elseif(-not $Silent)
{
Write-Host "The actual version of the $Item ($ActualVersion) does not fit the required ($RequiredVersion)." -ForegroundColor Red
}
return $retval
}
function Refresh-Path {
$machine = [Environment]::GetEnvironmentVariable("Path", "Machine")
$user = [Environment]::GetEnvironmentVariable("Path", "User")
$env:Path = "$machine;$user"
}
Refresh-Path
####################################################################################
# WINGET #
####################################################################################
$winget = Get-Command winget -ErrorAction SilentlyContinue
if (-not $winget) {
Write-Host "winget is not available on this system." -ForegroundColor Red
$wingetGuide = @"
To install winget:
1. Proceed to: https://learn.microsoft.com/en-us/windows/package-manager/winget/.
2. Follow the on-site instructions to download and install winget.
"@
Write-Host $wingetGuide -ForegroundColor Yellow
exit 1
}
####################################################################################
# NODE.JS #
####################################################################################
# Function to check if required version of Node.js is installed
function VerifyNode {
param
(
[Parameter(Mandatory)][string]$RequiredVersion
)
$retval = $false
# Allow Major.Minor, Major.Minor.Patch, or extended build versions (e.g. 16.11.36631.11)
if ($RequiredVersion -notmatch '^\d+\.\d+(\.\d+){0,2}$') {
Write-Host "RequiredVersion must be 'Major.Minor' (e.g. 8.0), 'Major.Minor.Patch' (e.g. 8.0.2), or extended (e.g. 16.11.36631.11)." -ForegroundColor Red
return $retval
exit 1
}
try
{
$nodeVersion = (node -v).TrimStart('v')
if(MajorMinorBuildRevisionEqualOrHigher -Item "Node.js" -ActualVersion $nodeVersion -RequiredVersion $RequiredVersion)
{
$retval = $true
}
}
catch
{
Write-Host "Node.js is not installed or not found in PATH." -ForegroundColor Red
$retval = $false
return $retval
}
return $retval
}
# Function to download and install Node.js
function InstallNode{
param([Parameter(Mandatory)][string]$RequiredVersion)
Write-Host "Installing Node.js LTS via winget..."
$packageId = "OpenJS.NodeJS.LTS"
winget install `
--id $packageId `
--exact `
--silent `
--accept-package-agreements `
--accept-source-agreements
$env:Path = "$env:ProgramFiles\nodejs;$env:Path"
# Verify
$nodeVersion = (node -v).Trim()
if(-not $nodeVersion)
{
Write-Host "Error installing Node.js." -ForegroundColor Red
exit 1
}
else
{
Write-Host "Node.js succefully installed." -ForegroundColor Green
}
node -v
}
# Check Node
if (-not (VerifyNode -RequiredVersion $nodeRequiredVersion))
{
$response = Read-Host "Node.js $nodeRequiredVersion is not installed. Would you like to install it now? (Y/N)"
if ($response -eq 'Y' -or $response -eq 'y') {
InstallNode -RequiredVersion $nodeRequiredVersion
}
}
####################################################################################
# MICROSOFT VISUAL C++ REDISTRIBUTABLE #
####################################################################################
# Function to check if required version of Microsoft Visual C++ Redistributable is installed
function VerifyVcp {
param
(
[Parameter(Mandatory)][string]$RequiredVersion
)
$retval = $false
# Allow Major.Minor, Major.Minor.Patch, or extended build versions (e.g. 16.11.36631.11)
if ($RequiredVersion -notmatch '^\d+\.\d+(\.\d+){0,2}$') {
Write-Host "RequiredVersion must be 'Major.Minor' (e.g. 8.0), 'Major.Minor.Patch' (e.g. 8.0.2), or extended (e.g. 16.11.36631.11)." -ForegroundColor Red
return $retval
exit 1
}
$vc = Get-ItemProperty $VcpRegPath -ErrorAction SilentlyContinue
$actualVersion = $vc.Version.TrimStart('v')
if ($vc -and $vc.Installed -eq 1 -and (MajorMinorBuildRevisionEqualOrHigher -Item "VC++ Redistributable" -ActualVersion $actualVersion -RequiredVersion $RequiredVersion))
{
$retval = $true
}
if ($retval)
{
Write-Host "VC++ Redistributable $RequiredVersion detected." -ForegroundColor Green
}
else
{
Write-Host "VC++ Redistributable $RequiredVersion is not installed." -ForegroundColor Red
}
return $retval
}
# Function to download and install Microsoft Visual C++ Redistributable
function InstallVcp{
param([Parameter(Mandatory)][string]$RequiredVersion)
$installer = "$env:TEMP\vc_redist.x64.exe"
Write-Host "Downloading VC++ Redistributable..."
Invoke-WebRequest $VcpUrl -OutFile $installer
Write-Host "Installing VC++ Redistributable..."
Start-Process $installer -ArgumentList '/install /quiet /norestart' -Wait
Start-Sleep -Seconds 5
if (-not (VerifyVcp -RequiredVersion $RequiredVersion)) {
Write-Host "Error installing VC++ Redistributable ." -ForegroundColor Red
exit 1
}
Write-Host "VC++ Redistributable $RequiredVersion installed successfully." -ForegroundColor Green
}
# Check VerifyVcp Visual C++ Redistributable
if (-not (VerifyVcp -RequiredVersion $VCpRequiredVersion))
{
$response = Read-Host "Microsoft Visual C++ Redistributable $VCpRequiredVersion is not installed. Would you like to install it now? (Y/N)"
if ($response -eq 'Y' -or $response -eq 'y') {
InstallVcp -RequiredVersion $VCpRequiredVersion
}
}
####################################################################################
# GIT #
####################################################################################
# Function to check if required version of Git is installed
function VerifyGit {
param
(
[Parameter(Mandatory)][string]$RequiredVersion
)
$retval = $false
# Allow Major.Minor, Major.Minor.Patch, or extended build versions (e.g. 16.11.36631.11)
if ($RequiredVersion -notmatch '^\d+\.\d+(\.\d+){0,2}$') {
Write-Host "RequiredVersion must be 'Major.Minor' (e.g. 8.0), 'Major.Minor.Patch' (e.g. 8.0.2), or extended (e.g. 16.11.36631.11)." -ForegroundColor Red
return $retval
exit 1
}
try
{
$actualVersion = git --version | Select-String -Pattern '([0-9]+\.[0-9]+\.[0-9]+)' | ForEach-Object { $_.Matches[0].Value }
if(MajorMinorBuildRevisionEqualOrHigher -Item "Git" -ActualVersion $actualVersion -RequiredVersion $RequiredVersion)
{
$retval = $true
}
}
catch
{
Write-Host "Git is not installed." -ForegroundColor Red
$retval = $false
return $retval
}
return $retval
}
# Function to download and install Git
function InstallGit{
param([Parameter(Mandatory)][string]$RequiredVersion)
Write-Host "Installing Git via winget..."
$packageId = "Git.Git"
winget install `
--id $packageId `
--exact `
--silent `
--accept-package-agreements `
--accept-source-agreements
Start-Sleep -Seconds 10
Refresh-Path
if (-not (VerifyGit -RequiredVersion $RequiredVersion)) {
Write-Host "Error installing Git." -ForegroundColor Red
exit 1
}
Write-Host "Git $RequiredVersion installed successfully." -ForegroundColor Green
}
# Check Git
if (-not (VerifyGit -RequiredVersion $gitRequiredVersion))
{
$response = Read-Host "Git $gitRequiredVersion is not installed. Would you like to install it now? (Y/N)"
if ($response -eq 'Y' -or $response -eq 'y') {
InstallGit -RequiredVersion $gitRequiredVersion
}
}
####################################################################################
# DOT NET SDK #
####################################################################################
# Function to check if required version of dotnet SDK is installed
function VerifyDotNetSDK {
param
(
[Parameter(Mandatory)][string]$RequiredVersion
)
$retval = $false
# Allow Major.Minor, Major.Minor.Patch, or extended build versions (e.g. 16.11.36631.11)
if ($RequiredVersion -notmatch '^\d+\.\d+(\.\d+){0,2}$') {
Write-Host "RequiredVersion must be 'Major.Minor' (e.g. 8.0), 'Major.Minor.Patch' (e.g. 8.0.2), or extended (e.g. 16.11.36631.11)." -ForegroundColor Red
return $retval
exit 1
}
$dotnetDir = Join-Path $env:ProgramFiles "dotnet"
$dotnetExe = Join-Path $dotnetDir "dotnet.exe"
if (-not (Test-Path -LiteralPath $dotnetDir))
{
Write-Host "Directory $dotnetDir not found." -ForegroundColor Red
$retval = $false
return $retval
exit 0
}
if (-not (Test-Path -LiteralPath $dotnetExe))
{
Write-Host "dotnet.exe not found at '$dotnetExe' (PATH may not be updated yet)." -ForegroundColor Red
$retval = $false
return $retval
exit 0
}
$existingUserPath = [Environment]::GetEnvironmentVariable("PATH", "User")
if ($existingUserPath -notlike "*$dotnetDir*")
{
$newUserPath = "$dotnetDir;$existingUserPath"
[Environment]::SetEnvironmentVariable("PATH", $newUserPath, "User")
Refresh-Path
}
$dotnetSDKs = & dotnet --list-sdks 2>$null
foreach ($sdk in $dotnetSDKs)
{
if ($sdk -match "^$([regex]::Escape($RequiredVersion))\s") {
$retval = $true
break
}
}
if ($retval)
{
Write-Host ".NET $RequiredVersion SDK detected." -ForegroundColor Green
}
else
{
Write-Host ".NET $RequiredVersion SDK is not installed." -ForegroundColor Red
}
return $retval
}
# Function to download and install dotnet SDK
function InstallDotNetSDK {
param([Parameter(Mandatory)][string]$RequiredVersion)
$dotnetInstall = "dotnet-install.ps1"
$installDir = Join-Path $env:ProgramFiles "dotnet"
try {
Write-Host "Downloading $dotnetInstall..."
Write-Host " The installer will request to run as administrator. Expect a prompt." -ForegroundColor Yellow
Invoke-WebRequest -Uri $dotNetInstallationScriptLocation -OutFile $dotnetInstall
if (-not (Test-Path -LiteralPath $dotnetInstall)) {
Write-Host "Failed to download $dotnetInstall." -ForegroundColor Red
exit 1
}
$scriptPath = Join-Path $PSScriptRoot $dotnetInstall
Write-Host "Installing .NET SDK $RequiredVersion to $installDir"
$arguments = @(
"-NoProfile"
"-ExecutionPolicy Bypass"
"-File `"$scriptPath`""
"-Version `"$RequiredVersion`""
"-InstallDir `"$installDir`""
"-NoPath" # we'll set PATH ourselves in this session (reliable)
)
$proc = Start-Process powershell.exe -ArgumentList ($arguments -join ' ') -Verb RunAs -Wait -PassThru
if ($proc.ExitCode -ne 0) {
Write-Host "dotnet-install.ps1 failed with exit code $($proc.ExitCode)" -ForegroundColor Red
exit 1
}
# Make dotnet available in *this* PowerShell session:
$env:DOTNET_ROOT = $installDir
if ($env:PATH -notlike "*$installDir*")
{
$env:PATH = "$installDir;$env:PATH"
}
# Persist PATH for the current user (future shells)
$existingUserPath = [Environment]::GetEnvironmentVariable("PATH", "User")
if ($existingUserPath -notlike "*$installDir*")
{
$newUserPath = "$installDir;$existingUserPath"
[Environment]::SetEnvironmentVariable("PATH", $newUserPath, "User")
}
$dotnetInstalled = VerifyDotNetSDK -RequiredVersion $RequiredVersion
if (-not $dotnetInstalled) {
Write-Host "Error installing dotnet (or dotnet not visible in this session)." -ForegroundColor Red
exit 1
}
Write-Host ".NET SDK $RequiredVersion installed successfully." -ForegroundColor Green
}
catch {
Write-Host "Error installing dotnet: $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
finally {
# cleanup silently
Remove-Item -Path (Join-Path $PSScriptRoot $dotnetInstall) -Force -ErrorAction SilentlyContinue
}
}
# Check .NET SDK
if (-not (VerifyDotNetSDK -RequiredVersion $dotNetSDKRequiredVersion))
{
$response = Read-Host ".NET $dotNetSDKRequiredVersion SDK is not installed. Would you like to install it now? (Y/N)"
if ($response -eq 'Y' -or $response -eq 'y') {
InstallDotNetSDK -RequiredVersion $dotNetSDKRequiredVersion
}
}
####################################################################################
# DOT NET DESKTOP RUNTIME #
####################################################################################
# Function to check if required version of dotnet desktop runtime is installed
function VerifyDotNetDesktopRuntime {
param
(
[Parameter(Mandatory)][string]$RequiredVersion,
[Parameter(Mandatory)][ValidateSet("x86","x64")][string]$Architecture
)
$retval = $false
# Allow Major.Minor, Major.Minor.Patch, or extended build versions (e.g. 16.11.36631.11)
if ($RequiredVersion -notmatch '^\d+\.\d+(\.\d+){0,2}$') {
Write-Host "RequiredVersion must be 'Major.Minor' (e.g. 8.0), 'Major.Minor.Patch' (e.g. 8.0.2), or extended (e.g. 16.11.36631.11)." -ForegroundColor Red
return $retval
exit 1
}
$dotnetDir = if ($Architecture -eq "x86")
{
Join-Path ${env:ProgramFiles(x86)} "dotnet"
}
else
{
Join-Path $env:ProgramFiles "dotnet"
}
$dotnetExe = Join-Path $dotnetDir "dotnet.exe"
if (-not (Test-Path -LiteralPath $dotnetDir))
{
Write-Host "Directory $dotnetDir not found." -ForegroundColor Red
$retval = $false
return $retval
exit 0
}
if (-not (Test-Path -LiteralPath $dotnetExe))
{
Write-Host "dotnet.exe not found at '$dotnetExe' (PATH may not be updated yet)." -ForegroundColor Red
$retval = $false
return $retval
exit 0
}
if ($Architecture -eq "x64")
{
$existingUserPath = [Environment]::GetEnvironmentVariable("PATH", "User")
if ($existingUserPath -notlike "*$dotnetDir*")
{
$newUserPath = "$dotnetDir;$existingUserPath"
[Environment]::SetEnvironmentVariable("PATH", $newUserPath, "User")
Refresh-Path
}
}
if ($Architecture -eq "x86")
{
$runtimes = & $dotnetExe --list-runtimes 2>$null
}
else
{
$runtimes = & dotnet --list-runtimes 2>$null
}
# Extract versions like 8.0.1, 8.0.12, etc.
$versions = foreach ($line in $runtimes)
{
if ($line -match '^Microsoft\.WindowsDesktop\.App\s+([\d\.]+)\s')
{
[version]$matches[1]
}
}
foreach ($version in $versions) {
if (MajorMinorEqualBuildRevisionEqualOrHigher -Item "DOT NET DESKTOP RUNTIME" -ActualVersion $version -RequiredVersion $RequiredVersion -Silent)
{
$retval = $true
break
}
}
if ($retval)
{
Write-Host ".NET $dotNetDesktopRuntimeRequiredVersion runtime $Architecture detected." -ForegroundColor Green
}
else
{
Write-Host ".NET $dotNetDesktopRuntimeRequiredVersion runtime $Architecture is not installed." -ForegroundColor Red
}
return $retval
}
# Function to download and install dotnet desktop runtime
function InstallDotNetDesktopRuntime {
param
(
[Parameter(Mandatory)][string]$RequiredVersion,
[Parameter(Mandatory)][ValidateSet("x86","x64")][string]$Architecture
)
$retval = $false
# Allow Major.Minor, Major.Minor.Patch, or extended build versions (e.g. 16.11.36631.11)
if ($RequiredVersion -notmatch '^\d+\.\d+(\.\d+){0,2}$') {
Write-Host "RequiredVersion must be 'Major.Minor' (e.g. 8.0), 'Major.Minor.Patch' (e.g. 8.0.2), or extended (e.g. 16.11.36631.11)." -ForegroundColor Red
return $retval
exit 1
}
$channel = ($RequiredVersion -split '\.')[0..1] -join '.'
$url = "https://aka.ms/dotnet/$channel/windowsdesktop-runtime-win-$Architecture.exe"
$installer = Join-Path $env:TEMP "dotnet-desktop-runtime-$channel-$Architecture.exe"
Write-Host "Downloading .NET Desktop Runtime $channel ($Architecture)..."
Write-Host " The installer will request to run as administrator. Expect a prompt." -ForegroundColor Yellow
Invoke-WebRequest -Uri $url -OutFile $installer -UseBasicParsing
Write-Host "Installing .NET Desktop Runtime $channel ($Architecture)..."
$proc = Start-Process -FilePath $installer -ArgumentList "/install /quiet /norestart" -Verb RunAs -Wait -PassThru
if ($proc.ExitCode -ne 0)
{
Write-Host ".NET Desktop Runtime $channel ($Architecture) installation failed with exit code $($proc.ExitCode)." -ForegroundColor Red
return $retval
exit 1
}
# Verify post-install
if (-not (VerifyDotNetDesktopRuntime -RequiredVersion $RequiredVersion -Architecture $Architecture))
{
Write-Host "Installation completed but verification failed for .NET Desktop Runtime $RequiredVersion ($Architecture)." -ForegroundColor Red
return $retval
exit 1
}
Write-Host ".NET Desktop Runtime $RequiredVersion ($Architecture) installed successfully." -ForegroundColor Green
}
# Check .NET desktop runtime x86
if (-not (VerifyDotNetDesktopRuntime -RequiredVersion $dotNetDesktopRuntimeRequiredVersion -Architecture x86))
{
$response = Read-Host ".NET $dotNetDesktopRuntimeRequiredVersion runtime x86 is not installed. Would you like to install it now? (Y/N)"
if ($response -eq 'Y' -or $response -eq 'y')
{
InstallDotNetDesktopRuntime -RequiredVersion $dotNetDesktopRuntimeRequiredVersion -Architecture x86
}
}
# Check .NET desktop runtime x64
if (-not (VerifyDotNetDesktopRuntime -RequiredVersion $dotNetDesktopRuntimeRequiredVersion -Architecture x64))
{
$response = Read-Host ".NET $dotNetDesktopRuntimeRequiredVersion runtime x64 is not installed. Would you like to install it now? (Y/N)"
if ($response -eq 'Y' -or $response -eq 'y')
{
InstallDotNetDesktopRuntime -RequiredVersion $dotNetDesktopRuntimeRequiredVersion -Architecture x64
}
}
####################################################################################
# AX CODE #
####################################################################################
# Define the command to get the version
$command = "axcode --version"
# Execute the command and capture the output
try
{
$version = Invoke-Expression $command
$ActualVersion = $version.Item(0)
# Compare the retrieved version with the expected version
if (-not (MajorMinorBuildRevisionEqualOrHigher -Item "AX Code" -ActualVersion $ActualVersion -RequiredVersion $axCodeRequiredVersion))
{
Write-Host "The AXCode version does not match the expected version: $axCodeRequiredVersion. It's highly recommended to update it." -ForegroundColor Red
}
}
catch
{
Write-Host "Error: Unable to determine the AXCode version. Ensure AXCode is correctly installed and accessible from the command line." -ForegroundColor Red
$axCodeGuide = @"
1. Ensure that you have a valid SIMATIC AX license.
2. Verify that you have access to $axCodeDownloadUrl.
3. Download AX Code for Windows from $axCodeDownloadUrl.
4. Install AX Code for Windows.
5. Restart your computer.
6. Run this script again.
"@
Write-Host "To install the AXCode:" -ForegroundColor Yellow
Write-Host $axCodeGuide -ForegroundColor Yellow
exit 1
}
####################################################################################
# APAX INSTALATION #
####################################################################################
$isApaxInstalled = $false
try
{
$apaxVersion = (apax --version).Trim()
# Compare the retrieved version with the expected version
if ((MajorMinorBuildRevisionEqualOrHigher -Item "APAX" -ActualVersion $apaxVersion -RequiredVersion $apaxRequiredVersion))
{
$isApaxInstalled = $true
}
else
{
Write-Host "The APAX version does not match the expected version: $apaxRequiredVersion. It's highly recommended to update it." -ForegroundColor Red
}
}
catch
{
Write-Host "Apax is not installed or not found in PATH. You need to have valid SIMATIC-AX license." -ForegroundColor Red
try
{
$nodeVersion = (node -v).Trim()
}
catch
{
Write-Host "Node.js is not installed or not found in PATH." -ForegroundColor Red
Write-Host "Installing Node.js LTS via winget..."
$packageId = "OpenJS.NodeJS.LTS"
$winget = Get-Command winget -ErrorAction SilentlyContinue
if (-not $winget) {
Write-Host "winget is not available on this system." -ForegroundColor Red
exit 1
}
winget install `
--id $packageId `
--exact `
--silent `
--accept-package-agreements `
--accept-source-agreements
$env:Path = "$env:ProgramFiles\nodejs;$env:Path"
# Verify
node -v
npm -v
}
}
# Check for Apax - Assuming there's a direct link for Apax
# (Note: You might want to guide users more specifically since Apax's installation might not be as straightforward as opening a URL.)
if (-not $isApaxInstalled) {
$apaxGuide = @"
To download Apax:
1. Proceed to: $axCodeDownloadUrl in your browser.
2. Log in with your credentials.
3. Follow the on-site instructions to download and install Apax.
"@
Write-Host "Apax is not installed or not found in PATH. You need to have a valid SIMATIC-AX license." -ForegroundColor Yellow
Write-Host $apaxGuide -ForegroundColor Yellow
}
####################################################################################
# APAX LOGIN AX #
####################################################################################
$accessToApax = $false;
if($isApaxInstalled)
{
try
{
# Just check the access by trying to get the feed
$response = Invoke-RestMethod -Uri $apaxUrl -Method Get
Write-Host "Feed: $apaxUrl accessible by means of network." -ForegroundColor Green
$accessToApax = $true;
}
catch
{
Write-Host "Failed to access feed: $apaxUrl. Error: $($_.Exception.Message)" -ForegroundColor Red
Write-Host "Try to access it manually, check your connection, firewall setttings, etc. " -ForegroundColor Red
}
}
# Check for apax
$isApaxAccessible = $false
try {
$command = "apax info --ax-scopes"
$resp = cmd /c $command '2>&1'
Write-Host "resp $resp" -ForegroundColor Yellow
if($resp[2].ToString().Contains("No access to the Simatic-AX registry"))
{
Write-Host "Unable to access apax packages." -ForegroundColor Red
Write-Host "$errorOutput" -ForegroundColor Red
$apaxGuide = @"
1. Check your connections, firewall, credentials etc.
2. Proceed to: $apaxUrl in your browser aand verify that it is accessible.
3. Log in with your credentials.
4. In the AX code environment run 'apax login' command.
5. Choose the 'AX (for Apax packages and IDE extensions)'
6. Log in with your credentials.
7. Run this script again.
"@
Write-Host $apaxGuide -ForegroundColor Yellow
exit 1
}
else
{
Write-Host "Apax packages are accessible." -ForegroundColor Green
$isApaxAccessible = $true;
}
}
catch
{
Write-Host "Error: Unable to access apax packages. Check your connections, firewall, credentials etc. : $($_.Exception.Message)" -ForegroundColor Red
exit 1
}
####################################################################################
# APAX LOGIN INXTON #
####################################################################################
# Check the access to the external @inxton registry
$jsonData = Get-Content -Raw -Path "$env:USERPROFILE\.apax\auth.json" | ConvertFrom-Json
# Check if the registry exists and extract values
if ($jsonData.PSObject.Properties.Name -contains $inxtonRegistryUrl)
{
$registryToken = $jsonData.$inxtonRegistryUrl.registryToken
$userName = $jsonData.$inxtonRegistryUrl.userName
$jsonFile = $env:USERPROFILE
$maskedPath = $jsonFile -replace '\\[^\\]+$', '\<current_user_name>\.apax\auth.json'
if ($registryToken.Length -gt 6)
{
$maskedToken = $registryToken.Substring(0,5) + ("*" * ($registryToken.Length - 6)) + $registryToken[-1]
}else
{
$maskedToken = "*" * $registryToken.Length
}
if ($userName.Length -gt 2)
{
$maskedUserName = $userName.Substring(0,1) + ("*" * ($userName.Length - 2)) + $userName[-1]
}else
{
$maskedUserName = "*" * $userName.Length
}
Write-Host "Registry $inxtonRegistryUrl found in $maskedPath!" -ForegroundColor Green
Write-Host "Registry Token: $maskedToken" -ForegroundColor Green
Write-Host "User Name: $maskedUserName" -ForegroundColor Green
}else
{
Write-Host "Registry '$inxtonRegistryUrl' not found in $maskedPath." -ForegroundColor Red
$registryGuide = @"
1. Generate a Personal Access Token on GitHub with 'read:packages' permissions (at least).
2. In AX code environment run 'apax login' command.
3. Choose the 'Custom NPM registry'
4. Enter the registry URL: $inxtonRegistryUrl
5. Enter your username
6. Enter your personal access token
7. Run this script again.
Note: Treat your personal access token like a password. Keep it secure and do not share it.
"@
Write-Host "You need to provide apax login to external registry." -ForegroundColor Yellow
Write-Host $registryGuide -ForegroundColor Yellow
exit 1
}
$headers = @{
"Authorization" = "Bearer $userToken"
"User-Agent" = "PowerShell"
"Accept" = "application/vnd.github.package-preview+json"
}
# Check if the feed is added
$isFeedAlreadyAdded = $false;
try
{
$feeds=$(dotnet nuget list source)
$isFeedAlreadyAdded = $feeds | Select-String -Pattern $nugetFeedUrl
if ($isFeedAlreadyAdded)
{
Write-Host "The NuGet feed with URL $nugetFeedUrl is already added." -ForegroundColor Green
}
else
{
Write-Host "The NuGet feed with URL $nugetFeedUrl is not added." -ForegroundColor Red
Write-Host "You will need to add $nugetFeedUrl to your nuget sources manually (more information in src/README.md)." -ForegroundColor Red
}
}
catch
{
Write-Host "Check if the NuGet feed with URL $nugetFeedUrl is properly added to your nuget sources." -ForegroundColor Red
}
# Check if the feed is accessible by means of network
$hasFeedAccess = $false;
if($isFeedAlreadyAdded)
{
try
{
# Just check the access by trying to get the feed
$response = Invoke-RestMethod -Uri $nugetFeedUrl -Headers $headers -Method Get
Write-Host "Feed: $nugetFeedUrl accessible by means of network." -ForegroundColor Green
$hasFeedAccess = $true;
}
catch
{
Write-Host "Failed to access feed: $nugetFeedUrl. Error: $($_.Exception.Message)" -ForegroundColor Red
Write-Host "Try to access it manually, check your connection, firewall setttings, etc. " -ForegroundColor Red
}
}
$hasFeedAutorization = $false;
if($hasFeedAccess)
{
try
{
# $response = dotnet tool update axsharp.ixc --prerelease
$status = $?
if($status -match "^(?i)true$")
{
write-host "Authentification passed successfully while accessing feed $nugetFeedUrl." -foregroundcolor green
$hasfeedautorization = $true;
}
else
{
Write-Host "Authentification error when trying to access the feed $nugetFeedUrl. " -ForegroundColor Red
}
}
catch
{
Write-Host "Authentification error when trying to access the feed $nugetFeedUrl : $($_.Exception.Message)" -ForegroundColor Red
}
}
if(-not ($isFeedAlreadyAdded -and $hasFeedAccess -and $hasFeedAutorization))
{
$nugetGuide = @"
To manually add the GitHub NuGet feed to your sources:
1. Generate a Personal Access Token on GitHub with 'read:packages', 'write:packages', and 'delete:packages' (if needed) permissions.
2. Open a command prompt or terminal.
3. Use the following command to add the feed to your NuGet sources:
dotnet nuget add source --username [YOUR_GITHUB_USERNAME] --password [YOUR_PERSONAL_ACCESS_TOKEN] --store-password-in-clear-text --name gh-packages-inxton $nugetFeedUrl
Replace [YOUR_GITHUB_USERNAME] with your actual GitHub username and [YOUR_PERSONAL_ACCESS_TOKEN] with the token you generated.
Note: Treat your personal access token like a password. Keep it secure and do not share it.
"@
Write-Host "You need to add the GitHub NuGet feed to your sources manually." -ForegroundColor Yellow
Write-Host $nugetGuide -ForegroundColor Yellow
exit 0
}
####################################################################################
# VISUAL STUDIO BUILD TOOLS #
####################################################################################
# Check if VS Build Tools is installed
function Verify-VSBuildTools
{
param
(
[Parameter(Mandatory)][string]$RequiredVersion
)
$retval = $false
# Allow Major.Minor, Major.Minor.Patch, or extended build versions (e.g. 16.11.36631.11)
if ($RequiredVersion -notmatch '^\d+\.\d+(\.\d+){0,2}$') {