forked from goshoom/d365fo-workspace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
D365FOWorkspace.psm1
269 lines (221 loc) · 8.3 KB
/
D365FOWorkspace.psm1
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
# Depends on d365fo.tools
# Load defaults
$configFile = Get-ChildItem "$PSScriptRoot\config.ps1"
. $configFile.FullName
function Switch-FOWorkspace
{
<#
.SYNOPSIS
Tells F&O (and F&O tools for Visual Studio) where to find source control and binaries.
#>
param (
[string] $WorkspaceDir # = (Get-Location)
)
# You can modify these variables or expose them as function parameters
$switchPackages = $true
$switchVsDefaultProjectsPath = $true
[string]$workspaceMetaDir = Join-Path $WorkspaceDir 'Metadata'
[string]$workspaceProjectsDir = Join-Path $WorkspaceDir 'Projects'
# Load DEV config file
$devConfigPath = $env:USERPROFILE + '\Documents\Visual Studio Dynamics 365\DynamicsDevConfig.xml'
if (-Not (Test-Path $devConfigPath))
{
throw 'Dynamics DEV config file was not found.'
}
[xml]$devConfig = Get-Content $devConfigPath
$webRoot = $devConfig.DynamicsDevConfig.WebRoleDeploymentFolder
$webConfigPath = $webRoot + '\web.config'
[xml]$webConfig = Get-Content $webConfigPath
$activeWorkspace = Get-FOWorkspace
Write-Host "Previous workspace: $activeWorkspace"
# Update path to packages
if ($switchPackages)
{
Stop-D365Environment -ShowOriginalProgress
Start-Sleep -Seconds 60
$appSettings = $webConfig.configuration.appSettings
$appSettings.SelectSingleNode("add[@key='Aos.MetadataDirectory']").Value = $workspaceMetaDir
$appSettings.SelectSingleNode("add[@key='Aos.PackageDirectory']").Value = $workspaceMetaDir
$appSettings.SelectSingleNode("add[@key='bindir']").Value = $workspaceMetaDir
$appSettings.SelectSingleNode("add[@key='Common.BinDir']").Value = $workspaceMetaDir
$appSettings.SelectSingleNode("add[@key='Microsoft.Dynamics.AX.AosConfig.AzureConfig.bindir']").Value = $workspaceMetaDir
$appSettings.SelectSingleNode("add[@key='Common.DevToolsBinDir']").Value = (Join-Path $workspaceMetaDir 'bin').ToString()
$webConfig.Save($webConfigPath)
}
$activeWorkspace = Get-FOWorkspace
Write-Host "Active workspace: $activeWorkspace"
# Switch the default path for new projects in Visual Studio
if ($switchVsDefaultProjectsPath)
{
$versionNum = ""
switch ($VSVersion) {
"2017" { $versionNum = "15" }
"2019" { $versionNum = "16" }
Default { $versionNum = "17" } # 2022
}
$settingsFilePattern = "$($env:LocalAppData)\Microsoft\VisualStudio\$versionNum*\Settings\CurrentSettings.vssettings"
$settingsFile = Get-ChildItem $settingsFilePattern | Select-Object -First 1
if ($settingsFile)
{
[xml]$vsConfigXml = Get-Content $settingsFile
$options = $vsConfigXml.UserSettings.ToolsOptions
$envOptions = $options.SelectSingleNode("ToolsOptionsCategory[@name='Environment']")
$projOptions = $envOptions.SelectSingleNode("ToolsOptionsSubCategory[@name='ProjectsAndSolution']")
$projPathElement = $projOptions.SelectSingleNode("PropertyValue[@name='ProjectsLocation']")
if ($projPathElement.InnerText -ne $workspaceProjectsDir)
{
$projPathElement.InnerText = $workspaceProjectsDir
$vsConfigXml.Save($settingsFile)
Write-Information "Visual Studio configuration file updated"
}
else
{
Write-Warning "Visual Studio configuration file project location not updated"
}
}
else
{
Write-Warning "Visual Studio configuration file was not found."
}
}
}
function Get-FOWorkspace
{
<#
.SYNOPSIS
Shows the model store folder currently used by F&O.
#>
(Get-D365EnvironmentSettings).Aos.MetadataDirectory
}
function Add-FOPackageSymLinks
{
<#
.SYNOPSIS
Creates symbolic links for standard packages in D365FO.
.DESCRIPTION
Creates symbolic links for standard packages in D365FO. It requires admin permissions.
Because only custom packages are stored in version control, downloading code from Azure DevOps
creates a Metadata folder without standard packages (e.g. ApplicationSuite).
To be able to connect F&O (and F&O DEV tools) to this folder, we need standard packages as well.
One option would be copying standard packages there, but it's slow, it would waste disk space
and it would cause problems with updates.
Instead, we just create symbolic links to the folders.
#>
param (
[string] $WorkspaceDir # = (Get-Location)
)
if ((Test-Path $WorkspaceDir) -ne $true)
{
throw "Path does not exist."
}
if ((Split-Path $WorkspaceDir -Leaf) -eq 'Metadata')
{
$workspaceMetaDir = $WorkspaceDir;
}
else
{
$workspaceMetaDir = Join-Path $WorkspaceDir 'Metadata'
}
# For each folder in packages (it assumes that there are no custom packages)
foreach ($dir in (Get-ChildItem (Get-FOPackagesDir) -dir))
{
$targetDir = (Join-Path $workspaceMetaDir $dir.Name)
if (Test-Path $targetDir)
{
#If there is a already a folder of the same name as the symblic link, delete it
cmd /c rmdir /s /q $targetDir
}
# Create a symbolic link
New-Item -ItemType SymbolicLink -Path $targetDir -Target $dir.FullName -Force
}
}
function Get-FOPackagesDir
{
<#
.SYNOPSIS
Tries to find the location of F&O model store (PackagesLocalDirectory).
#>
if ($PackageDir -and (Test-Path -Path $PackageDir))
{
return $PackageDir
}
foreach ($drive in (Get-Volume | Where-Object OperationalStatus -eq OK | Where-Object DriveLetter -ne $null | Select-Object -Expand DriveLetter))
{
$path = "${drive}:\AosService\PackagesLocalDirectory"
if (Test-Path -Path $path)
{
return $path
}
}
throw "Cannot find PackagesLocalDirectory. Specify the path in $($configFile.FullName)."
}
function Compare-FOWebConfigFile
{
<#
.SYNOPSIS
Compares specific properties for the web.config file
#>
param (
[string] $BackupDir
)
# Load DEV config file
$devConfigPath = $env:USERPROFILE + '\Documents\Visual Studio Dynamics 365\DynamicsDevConfig.xml'
if (-Not (Test-Path $devConfigPath))
{
Write-Host "Error: Dynamics DEV config file was not found in $env:USERPROFILE."
return
}
[xml]$devConfig = Get-Content $devConfigPath
$webRoot = $devConfig.DynamicsDevConfig.WebRoleDeploymentFolder
$webConfigPath = Join-Path $webRoot 'web.config'
# Compare web.config file
$backupWebConfigPath = Join-Path $BackupDir ('web.config')
# Step 1: Ensure both files exist
if (!(Test-Path $webConfigPath -PathType Leaf) -or !(Test-Path $backupWebConfigPath -PathType Leaf))
{
Write-Host "Error: File $webConfigPath or Backup file $backupWebConfigPath does not exist."
return
}
# Step 2: Compare specific properties (adjust as needed)
$propertiesToCompare = @(
"Aos.MetadataDirectory",
"Aos.PackageDirectory",
"bindir",
"Common.BinDir",
"Microsoft.Dynamics.AX.AosConfig.AzureConfig.bindir",
"Common.DevToolsBinDir"
)
# Step 3: Load the content of both files as XML
[xml]$xmlContent = Get-Content $webConfigPath
[xml]$backupContent = Get-Content $backupWebConfigPath
foreach ($property in $propertiesToCompare)
{
# Step 4: Check if the property exists in the original file
$propertyNode = $xmlContent.configuration.appSettings.SelectSingleNode("add[@key='$property']")
if ($null -ne $propertyNode) {
# Step 5: Retrieve values for comparison from the original file
$value = $propertyNode.Value
# Step 6: Retrieve values for comparison from the backup file
$backupValueNode = $backupContent.configuration.appSettings.SelectSingleNode("add[@key='$property']")
if ($null -ne $backupValueNode) {
$backupValue = $backupValueNode.Value
# Step 7: Display the comparison result
Write-Host " Property: $property"
Write-Host " Current Value : $value"
Write-Host " Backup Value : $backupValue"
Write-Host " Values Match? : $($value -eq $backupValue)"
Write-Host ""
} else {
# Step 8: Display a message if the property does not exist in the backup file
Write-Host " Property: $property"
Write-Host " Does not exist in $backupWebConfigPath."
Write-Host ""
}
} else {
# Step 9: Display a message if the property does not exist in the original file
Write-Host " Property: $property"
Write-Host " Does not exist in $webConfigPath."
Write-Host ""
}
}
}