-
Notifications
You must be signed in to change notification settings - Fork 112
Expand file tree
/
Copy pathsetupPowerShell.ps1
More file actions
189 lines (159 loc) · 9.91 KB
/
setupPowerShell.ps1
File metadata and controls
189 lines (159 loc) · 9.91 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
# This script is run at image build time to install and configure the PowerShell modules that are preinstalled with Cloud Shell
param(
[Parameter(Mandatory = $True, Position = 0)]
[ValidateSet("Base", "Top")]
[System.String]
$Image
)
$ProgressPreference = 'SilentlyContinue' # Suppresses progress, which doesn't render correctly in docker
# PowerShellGallery PROD site
$prodGallery = 'https://www.powershellgallery.com/api/v2'
$script:pscloudshellBlob = $null # Version folder for the pscloudshell blob storage
$shareModulePath = ([System.Management.Automation.Platform]::SelectProductNameForDirectory('SHARED_MODULES'))
$modulePath = if ($shareModulePath) {$shareModulePath}else {Microsoft.PowerShell.Management\Join-Path $PSHOME 'Modules'}
$script:dockerfileDataObject = $null # json object holding data from dockerfile.data.json file
# In almost all cases, Cloud Shell pulls modules from the regular PowerShell Gallery or preview gallery at build time.
# In a few legacy cases, we include modules which are not intended for broader use. These are pulled from an Azure storage
# account using the code below.
# PSCloudShell depends on files under Azure blob storage. The name of 'folder' (Azure container) is the version number.
# Read the version info from the Dockerfile.Data.json. In such way, only the Dockerfile.Data.json to be updated if there is
# any version changes.
function Get-DockerfileData {
$dockerFileData = Microsoft.PowerShell.Management\Join-Path $PSScriptRoot -ChildPath 'Dockerfile.Data.json'
Write-Output "Calling Get-Content from $dockerFileData"
$script:dockerfileDataObject = Microsoft.PowerShell.Management\Get-Content $dockerFileData | Microsoft.PowerShell.Utility\ConvertFrom-Json
if (-not $script:dockerfileDataObject) {
throw "Error while reading $dockerFileData file."
}
$pscloudshellVer = $script:dockerfileDataObject.PSCloudShellVersion
Write-Output "pscloudshellVersion= $pscloudshellVer;"
}
# Install Azure and AzureAD (Active Directory) modules
# This function replaces the old poshtestgallery issue
function Install-AzAndAzAdModules {
Write-Output "Install-AzAndAdModules.."
mkdir temp
curl -o az-cmdlets.tar.gz -sSL "https://azpspackage.blob.core.windows.net/release/Az-Cmdlets-latest.tar.gz"
tar -xf az-cmdlets.tar.gz -C temp
rm az-cmdlets.tar.gz
cd temp
cp /usr/cloudshell/powershell/pkgs/azuread.standard.preview.0.0.0.10.nupkg ./AzureAD.Standard.Preview.nupkg
$SourceLocation = $PSScriptRoot
Write-Output "Source Location: $SourceLocation"
$gallery = [guid]::NewGuid().ToString()
Write-Output "Registering temporary repository $gallery with InstallationPolicy Trusted..."
Register-PSRepository -Name $gallery -SourceLocation $($pwd.providerPath) -PackageManagementProvider NuGet -InstallationPolicy Trusted
try {
Write-Output "Installing Az..."
Install-Module -Name Az -Repository $gallery -Scope AllUsers -AllowClobber -Force
Write-Output "Installing AzureAD.Standard.Preview..."
Install-Module -Name "AzureAD.Standard.Preview" -Repository $gallery -Scope AllUsers -AllowClobber -Force
}
finally {
Write-Output "Unregistering gallery $gallery..."
Unregister-PSRepository -Name $gallery
}
cd ..
rm -rf temp
}
# Download files from the PSCloudShell Azure storage blob
function Install-PSCloudShellFile {
param(
[string]$Source,
[string]$FileName,
[string]$Destination,
[string]$FileHash
)
$FullPath = Microsoft.PowerShell.Management\Join-Path -Path $Source -ChildPath $FileName
Write-Output "URL= $script:pscloudshellBlob/$FileName; FullPath= $FullPath; Destination=$Destination"
Microsoft.PowerShell.Utility\Invoke-WebRequest -Uri "$script:pscloudshellBlob/$FileName" -UseBasicParsing -OutFile $FullPath
$hash = (Microsoft.PowerShell.Utility\Get-FileHash $FullPath).Hash
if ($hash -eq $FileHash) {
Microsoft.PowerShell.Archive\Expand-Archive -Path $FullPath -DestinationPath $Destination -Verbose -Force
}
else {
throw "Hash mismatch for $FullPath. Expected: $FileHash Actual:$hash."
}
}
try {
# Get the pscloudshell version info and Az version info from from the ..\..\Windows\Dockerfile.Data.json
Get-DockerfileData
# Set up repo as trusted to avoid prompts
PowerShellGet\Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
$prodAllUsers = @{Repository = "PSGallery"; Scope = "AllUsers"}
if ($image -eq "Base") {
Write-Output "Installing modules from production gallery"
PowerShellGet\Install-Module -Name SHiPS @prodAllUsers
PowerShellGet\Install-Module -Name SQLServer -MaximumVersion $script:dockerfileDataObject.SQLServerModuleMaxVersion @prodAllUsers
PowerShellGet\Install-Module -Name MicrosoftPowerBIMgmt -MaximumVersion $script:dockerfileDataObject.PowerBIMaxVersion @prodAllUsers
PowerShellGet\Install-Module -Name MicrosoftTeams @prodAllUsers
# MS Graph packages
PowerShellGet\Install-Module -Name Microsoft.Graph.Authentication @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Graph.Users.Actions @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Graph.Users.Functions @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Graph.Groups @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Graph.Identity.DirectoryManagement @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Graph.Identity.Governance @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Graph.Identity.SignIns @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Graph.Applications @prodAllUsers
# Microsoft Entra PowerShell packages
PowerShellGet\Install-Module -Name Microsoft.Entra.Authentication @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.Users @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.Groups @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.DirectoryManagement @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.Governance @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.SignIns @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.Applications @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.Reports @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.Entra.CertificateBasedAuthentication @prodAllUsers
}
else {
# Installing modules from Azure Powershell and AzureAD
Write-Output "Installing modules from Azure Powershell and AzureAD"
Install-AzAndAzAdModules
# Install modules from PSGallery
Write-Output "Installing modules from production gallery"
PowerShellGet\Install-Module -Name AzurePSDrive @prodAllUsers
PowerShellGet\Install-Module -Name GuestConfiguration -MaximumVersion $script:dockerfileDataObject.GuestConfigurationMaxVersion -ErrorAction SilentlyContinue @prodAllUsers
PowerShellGet\Install-Module -Force PSReadLine @prodAllUsers
PowerShellGet\Install-Module -Name Az.Tools.Predictor @prodAllUsers
PowerShellGet\Install-Module -Name ExchangeOnlineManagement @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.PowerShell.SecretManagement @prodAllUsers
PowerShellGet\Install-Module -Name Microsoft.PowerShell.SecretStore @prodAllUsers
# With older base image builds, teams 1.1.6 is already installed
if (Get-Module MicrosoftTeams -ListAvailable) {
# For some odd reason, Update-Module was creating the MicrosoftTeams module twice with different version numbers.
# Uninstalling and then installing it again was the only way to keep it as one module.
Uninstall-Module MicrosoftTeams -Force
PowerShellGet\Install-Module -Name MicrosoftTeams @prodAllUsers
} else {
PowerShellGet\Install-Module -Name MicrosoftTeams @prodAllUsers
}
# Install PSCloudShell modules
$tempDirectory = Microsoft.PowerShell.Management\Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
$null = Microsoft.PowerShell.Management\New-Item -ItemType Directory $tempDirectory -ErrorAction SilentlyContinue
if (Microsoft.PowerShell.Management\Test-Path $tempDirectory) {
Write-Output ('Temp Directory: {0}' -f $tempDirectory)
}
# Copy the startup script to the all-users profile
$psStartupScript = Microsoft.PowerShell.Management\Join-Path $PSHOME 'PSCloudShellStartup.ps1'
Microsoft.PowerShell.Management\Copy-Item -Path $PSScriptRoot\PSCloudShellStartup.ps1 -Destination $psStartupScript
Write-Output "Installing powershell profile to $($PROFILE.AllUsersAllHosts)"
Microsoft.PowerShell.Management\Copy-Item -Path $psStartupScript -Destination $PROFILE.AllUsersAllHosts -Verbose
Write-Output "Installed powershell profile."
# Update PowerShell Core help files in the image, ensure any errors that result in help not being updated does not interfere with the build process
# We want the image to have latest help files when shipped.
Write-Output "Updating help files."
$null = Microsoft.PowerShell.Core\Update-Help -Scope AllUsers -Force -ErrorAction Ignore
Write-Output "Updated."
}
Write-Output "All modules installed:"
Write-Output (Get-InstalledModule | Sort-Object Name | Select-Object Name, Version, Repository)
}
finally {
# Clean-up the PowerShell Gallery registration settings
PowerShellGet\Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted -ErrorAction Ignore
if ($tempDirectory -and (Microsoft.PowerShell.Management\Test-Path $tempDirectory)) {
Microsoft.PowerShell.Management\Remove-Item $tempDirectory -Force -Recurse -ErrorAction Ignore
}
}