Subchapter 42.45
references/services/functions/consumption-to-flex/windows/dependency-scan.mdMarkdown13 KBView on GitHub
When: Phase 1 Assessment, after Step 2f, as . If the user skips, proceed — they own the runtime risk.
Walks the source tree for code, config, and packaging patterns that depend on Windows. Prefer source code because project manifests and API usage are directly inspectable. Use the deployed package from Step 3e only when source is unavailable; it confirms what is running but may contain compiled artifacts that reduce scan coverage. Findings populate §11 of the assessment report; ≥1 Blocker finding advisorily flips §1 Upgrade Readiness to Needs Attention (never hard-blocks).
⚠️ Heuristic aid, not a guarantee. This scan pattern-matches the most common Windows-only APIs, packages, RID targeting, and shell-outs to Windows tools. It is not exhaustive — uncommon Windows APIs, dynamically-loaded DLLs, transitive package dependencies, reflection-based calls, and runtime-generated code can slip past. The app owner is ultimately responsible for verifying their code has no Windows dependencies. False negatives are dangerous; false positives create friction. The scan’s job is to inform, not gate.
ask_user to explicitly request a local source directory or checked-out repository path; do not infer that the current workspace contains the function app. Explain that source provides the best scan coverage. If the user cannot provide source, offer the deployed package from Step 3e as a fallback. If they decline both, write “scan skipped” to §11 and stop.FUNCTIONS_WORKER_RUNTIME (captured in Step 2b). Always run the agnostic set + the matching per-language set.custom worker — agnostic set only; ask once if the handler is C#, Node, Java, Python, or PowerShell source and layer in that set if so.| # | Category |
|---|---|
| 1 | Win32 / WinRT / COM / WMI APIs |
| 2 | Path / case / line-ending / env-var assumptions |
| 3 | Windows certificate store |
| 4 | Windows registry |
| 5 | Windows-only packages |
| 6 | Windows-RID / net4x targeting |
| 7 | Windows-only PowerShell modules |
| 8 | Shelling out to Windows tools |
| Severity | Meaning | Effect on §1 |
|---|---|---|
| 🛑 Blocker | Will definitely fail on Linux (e.g. [DllImport("kernel32.dll")], Microsoft.Win32.Registry, System.Drawing.Common on .NET 6+, .exe handler for custom worker) | Needs Attention (advisory) |
| ⚠️ Likely | Often breaks but may be guarded (backslash paths, drive letters, RID-specific package refs) | None |
| ℹ️ Review | Heuristic worth a human eye (any P/Invoke, any external Process.Start, package name containing Windows) | None |
Each bullet below states a principle followed by anchor examples. Treat the examples as starting points, not as an exhaustive whitelist — when you encounter similar patterns that aren’t enumerated (a different system DLL, a different System.* namespace prefix, a different Windows admin exe, a different Windows-only PowerShell module, a different win32-flavored npm package name), flag them under the same category. The category headers in bold are the rule; the examples after the em-dash are how that rule commonly shows up.
Run for every worker runtime. Cite the category number on each finding.
@"C:\...", "D:\\...") or Windows env-var references in the %FOO% shape (%TEMP%, %USERPROFILE%, %WINDIR%, %PROGRAMFILES%, %APPDATA%, %LOCALAPPDATA%, …).Split("\r\n"), byte-exact file reads, anything that hard-codes \r\n line endings.cmd, powershell/pwsh, cscript, wscript, reg, wmic, tasklist, net, sc, iisreset, netsh, wevtutil, or any path ending .exe/.bat/.cmd/.ps1.\\.\ (devices, named pipes), \\?\ (Win32 long-path namespace), or \\.\pipe\ specifically. No Linux equivalent..csproj/.fsproj/launchSettings.json/Dockerfile/pipeline yaml referencing win-x64, win-x86, win-arm64, or win10-* outside a Windows-only condition.runtimes/win-*/ payload — deployment package contains runtimes/win-*/ without a matching runtimes/linux-x64/.[DllImport("<dll>")] of any Windows system DLL: kernel32, user32, advapi32, ole32, gdi32, shell32, ntdll, wininet, crypt32, etc.using directives, fully-qualified type names, or PackageReference whose namespace prefix exists only to wrap Windows. Match the prefix, not the leaf type. Known prefixes: System.Drawing.* (GDI+), System.DirectoryServices.* (ADSI/LDAP), System.Management.* (WMI), Microsoft.Win32.* (registry, scheduler), System.ServiceProcess.* (Windows services), Microsoft.Office.Interop.*.[ComImport], Marshal.GetActiveObject, Type.GetTypeFromProgID / …FromCLSID, Activator.CreateInstance of a COM type, or string-literal ProgIDs (WScript.Shell, Excel.Application, Word.Application, …).X509Store(StoreLocation.LocalMachine | CurrentUser). Linux uses an OpenSSL-backed store; behavior differs even where the API exists.Microsoft.Win32.Registry* (Registry.LocalMachine, Registry.CurrentUser, Registry.ClassesRoot, RegistryKey.*).<PackageReference> id matching *Windows*, *.Win32*, or *.Office.Interop.*. Specific offenders: System.Drawing.Common, System.Management, System.DirectoryServices.AccountManagement, Microsoft.Windows.Compatibility, WindowsAzure.Storage.<RuntimeIdentifier> / <RuntimeIdentifiers> containing any win-* (win-x64, win-x86, win-arm64, win10-*) without a matching linux-*.net4x target framework — <TargetFramework[s]> containing net4 (also in Known Limitations).Process.Start(...) / new ProcessStartInfo(...) whose executable matches the agnostic Windows-tool list.require/import of packages whose purpose is wrapping Windows. Naming patterns: node-windows-*, windows-*, win32-*. Known: node-windows, windows-shortcuts, windows-foreground-love, node-task-scheduler, edge/edge-js (CLR bridge), regedit.package.json deps matching the naming patterns above, or os: ["win32"] (refuses to install on Linux), or cpu constraints excluding Linux arches.node_modules/**/*.node files that are PE-format. Any .node shipped without a Linux-built equivalent fails to load. Solution: rebuild on Linux at deploy time.child_process.exec/spawn/execSync whose command matches the agnostic Windows-tool list.import of namespaces wrapping Windows: com.sun.jna.platform.win32.*, com.jacob.* (COM bridge), org.eclipse.swt.win32.*, anything ending in .win32. Also flag System.loadLibrary / System.load whose argument resolves to a .dll.pom.xml / build.gradle entries whose groupId:artifactId contains windows, win32, or jacob. Anchors: com.sun.jna:jna-platform, net.sf.jacob-project:jacob, org.eclipse.swt.win32.*..dll files under src/main/resources/, META-INF/native/, or shaded into the jar — won’t load on Linux even if the calling Java is portable.Runtime.exec(...) / new ProcessBuilder(...) whose command matches the agnostic Windows-tool list.import of any module in the win32* family (win32api, win32com, win32con, win32event, win32file, win32process, win32security, …), the registry interfaces (winreg, _winreg), or COM/WMI bridges (pythoncom, wmi, pywinauto, comtypes, pythonnet).ctypes.windll.*, ctypes.WinDLL(...), ctypes.OleDLL(...). The ctypes.windll attribute itself only exists on Windows Python.requirements.txt / pyproject.toml / Pipfile entries whose name signals Windows-only (pywin32, pywinauto, wmi, winshell, pythonnet, comtypes, win32-*) or pinned via sys_platform == 'win32' environment marker without an alternate branch.subprocess.run/Popen/call or os.system whose command matches the agnostic Windows-tool list.Flex Consumption packaging check: Inspect host.json, requirements.psd1, and the app-root Modules folder to determine whether the app relies on managed dependencies. Flex Consumption doesn’t support managed dependencies, even for Linux-compatible modules. If required modules aren’t bundled with the app, record that preparation is required in assessment report §11 and advise packaging them in Modules before deployment. Verify that the deployment package includes the required modules and their dependencies. Any source or packaging changes require user approval.
Get-WmiObject, Get-CimInstance, Invoke-WmiMethod, Invoke-CimMethod. PowerShell 7 on Linux silently returns null instead of erroring — failures are easy to miss.New-Object -ComObject …, Get-EventLog, Windows-service form of Get-Service/*-Service, anything in Microsoft.PowerShell.LocalAccounts.Registry:: provider: Get-ItemProperty Registry::*, Get-ChildItem HKLM: / HKCU: / HKCR:, Set-ItemProperty -Path HKLM:\…, New-PSDrive -PSProvider Registry.Import-Module of modules shipped only with Windows PowerShell, RSAT, or a Windows feature. Anchors: ActiveDirectory, GroupPolicy, ServerManager, Hyper-V, BitsTransfer, ScheduledTasks, MSOnline, AzureAD, Dism.Cert:\LocalMachine\* or Cert:\CurrentUser\*. Linux PowerShell has a limited read-only implementation.requirements.psd1 RequiredModules — pinning any module above.& cmd.exe …, Start-Process of a Windows binary, Invoke-Expression of any Windows admin command line.golang.org/x/sys/windows or calls to syscall.NewLazyDLL, windows.NewLazySystemDLL, or other Windows DLL-loading APIs.*_windows.go, //go:build windows constraints without a Linux implementation, or build/deployment configuration that sets GOOS=windows..exe or PE-format handler binaries without a Linux ELF equivalent.os/exec.Command or CommandContext whose executable matches the agnostic Windows-tool list.Run the agnostic set, plus:
file <handler> reports PE32+ executable … for MS Windows → 🛑 Blocker (must be rebuilt for Linux)..dll files in the package without matching .so / Linux ELF.host.json customHandler.description.defaultExecutablePath ending in .exe, .bat, .cmd, or .ps1.If the user identifies the handler’s source language as one of the supported seven, also layer in that set.
Each finding:
- category: 1-8
severity: blocker | likely | review
file: <relative path>
line: <line number, if applicable>
match: <the matched code or setting>
remediation: <one-line fix or "Migrate to Elastic Premium on Windows">Findings populate §11 Source Code Windows Dependency Scan of the assessment report — see the template in assessment.md. If the user declined the scan, write “User declined the source code dependency scan. Migration proceeded without static analysis of Windows dependencies.” in place of the findings table.