-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathpowershell.discover.ps1
More file actions
113 lines (93 loc) · 3.43 KB
/
powershell.discover.ps1
File metadata and controls
113 lines (93 loc) · 3.43 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
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
[CmdletBinding()]
param ()
function Get-CacheFilePath {
if ($IsWindows) {
Join-Path $env:LocalAppData "dsc\PowerShellDiscoverCache.json"
} else {
Join-Path $env:HOME ".dsc" "PowerShellDiscoverCache.json"
}
}
function Test-CacheValid {
param([string]$CacheFilePath, [string[]]$PSPaths)
if (-not (Test-Path $CacheFilePath)) {
return $false
}
try {
$cache = Get-Content -Raw $CacheFilePath | ConvertFrom-Json
foreach ($entry in $cache.PathInfo.PSObject.Properties) {
$path = $entry.Name
if (-not (Test-Path $path)) {
return $false
}
$currentLastWrite = (Get-Item $path).LastWriteTimeUtc
$cachedLastWrite = [DateTime]$entry.Value
if ($currentLastWrite -ne $cachedLastWrite) {
return $false
}
}
$cachedPaths = [string[]]$cache.PSModulePaths
if ($cachedPaths.Count -ne $PSPaths.Count) {
return $false
}
$diff = Compare-Object $cachedPaths $PSPaths
if ($null -ne $diff) {
return $false
}
return $true
} catch {
return $false
}
}
function Invoke-DscResourceDiscovery {
[CmdletBinding()]
param()
begin {
$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' }
$cacheFilePath = Get-CacheFilePath
$useCache = Test-CacheValid -CacheFilePath $cacheFilePath -PSPaths $psPaths
}
process {
if ($useCache) {
$cache = Get-Content -Raw $cacheFilePath | ConvertFrom-Json
$manifests = $cache.Manifests
} else {
$manifests = $psPaths | ForEach-Object -Parallel {
$searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml')
$enumOptions = [System.IO.EnumerationOptions]@{ IgnoreInaccessible = $false; RecurseSubdirectories = $true }
foreach ($pattern in $searchPatterns) {
try {
[System.IO.Directory]::EnumerateFiles($_, $pattern, $enumOptions) | ForEach-Object {
@{ manifestPath = $_ }
}
} catch { }
}
} -ThrottleLimit 10
$pathInfo = @{}
foreach ($path in $psPaths) {
if (Test-Path $path) {
$pathInfo[$path] = (Get-Item $path).LastWriteTimeUtc
}
}
$cacheObject = @{
PSModulePaths = $psPaths
PathInfo = $pathInfo
Manifests = $manifests
}
$cacheDir = Split-Path $cacheFilePath -Parent
if (-not (Test-Path $cacheDir)) {
New-Item -ItemType Directory -Path $cacheDir -Force | Out-Null
}
$cacheObject | ConvertTo-Json -Depth 10 | Set-Content -Path $cacheFilePath -Force
}
}
end {
if ($null -eq $manifests -or [string]::IsNullOrEmpty($manifests)) {
# Return nothing
} else {
$manifests | ForEach-Object { $_ | ConvertTo-Json -Compress }
}
}
}
Invoke-DscResourceDiscovery