Public/Import-OptionalWindowsFeaturesToIntune.ps1

<#
.SYNOPSIS
    Imports Optional Windows Features configuration to Intune.
.DESCRIPTION
    Creates Intune policy to disable insecure Windows Features and enable secure ones (Windows Sandbox, Hyper-V).
.EXAMPLE
    Import-OptionalWindowsFeaturesToIntune
#>

function Import-OptionalWindowsFeaturesToIntune {
    [CmdletBinding()]
    param(
        [switch]$DryRun
    )

    $ErrorActionPreference = "Stop"
    $workspacePath = Get-WorkspacePath
    if (-not $workspacePath) {
        Write-Error "Workspace not configured. Run Initialize-NLBaseline first."
        return
    }

    $config = Get-Config -WorkspacePath $workspacePath
    if (-not $config -or [string]::IsNullOrEmpty($config.AppRegistration.ClientId) -or [string]::IsNullOrEmpty($config.AppRegistration.ClientSecret) -or [string]::IsNullOrEmpty($config.AppRegistration.TenantId)) {
        Write-Error "App Registration not configured in config.json."
        return
    }

    Write-Host "`nImporting Optional Windows Features Policy to Intune`n" -ForegroundColor Cyan

    if ($DryRun) {
        Write-Host "[DryRun] Would create Optional Windows Features Policy" -ForegroundColor Cyan
        Write-Host "Features to disable:" -ForegroundColor Yellow
        Write-Host " - PowerShell v2 (old, no AMSI support)" -ForegroundColor White
        Write-Host " - Work Folders client" -ForegroundColor White
        Write-Host " - Internet Printing Client" -ForegroundColor White
        Write-Host " - Windows Media Player (legacy)" -ForegroundColor White
        Write-Host " - VBSCRIPT (deprecated)" -ForegroundColor White
        Write-Host " - Internet Explorer mode for Edge" -ForegroundColor White
        Write-Host " - WMIC (deprecated, insecure)" -ForegroundColor White
        Write-Host " - WordPad (deprecated)" -ForegroundColor White
        Write-Host " - PowerShell ISE (old, use VS Code)" -ForegroundColor White
        Write-Host " - Steps Recorder (deprecated)" -ForegroundColor White
        Write-Host "`nFeatures to enable:" -ForegroundColor Green
        Write-Host " - Windows Sandbox" -ForegroundColor White
        Write-Host " - Hyper-V" -ForegroundColor White
        return
    }

    if (-not $DryRun) {
        $connected = Connect-Intune -Config $config
        if (-not $connected) {
            Write-Error "Failed to connect to Microsoft Graph."
            return
        }
    }

    try {
        # Create OMA-URI settings for disabling insecure features
        $omaSettings = @()

        # Disable PowerShell v2
        $omaSettings += @{
            "@odata.type" = "#microsoft.graph.omaSettingInteger"
            displayName = "Disable PowerShell v2"
            description = "Disable PowerShell v2 (old, no AMSI support)"
            omaUri = "./Device/Vendor/MSFT/Policy/Config/WindowsOptionalFeatures/DisablePowerShellV2"
            value = 1
        }

        # Disable Work Folders
        $omaSettings += @{
            "@odata.type" = "#microsoft.graph.omaSettingInteger"
            displayName = "Disable Work Folders Client"
            description = "Disable Work Folders client (not needed outside domain)"
            omaUri = "./Device/Vendor/MSFT/Policy/Config/WindowsOptionalFeatures/DisableWorkFolders"
            value = 1
        }

        # Enable Windows Sandbox
        $omaSettings += @{
            "@odata.type" = "#microsoft.graph.omaSettingInteger"
            displayName = "Enable Windows Sandbox"
            description = "Enable Windows Sandbox for secure testing"
            omaUri = "./Device/Vendor/MSFT/Policy/Config/WindowsOptionalFeatures/EnableWindowsSandbox"
            value = 1
        }

        # Enable Hyper-V
        $omaSettings += @{
            "@odata.type" = "#microsoft.graph.omaSettingInteger"
            displayName = "Enable Hyper-V"
            description = "Enable Hyper-V for virtualization"
            omaUri = "./Device/Vendor/MSFT/Policy/Config/WindowsOptionalFeatures/EnableHyperV"
            value = 1
        }

        $policyDisplayName = "NLBaseline - Optional Windows Features"
        
        # Check if policy with same displayName already exists and remove it
        $removed = Remove-IntunePolicyByDisplayName -DisplayName $policyDisplayName -PolicyType "Configuration"
        if ($removed) {
            Write-Host "Removed existing policy: $policyDisplayName" -ForegroundColor Yellow
        }

        $body = @{
            "@odata.type" = "#microsoft.graph.windows10CustomConfiguration"
            displayName = $policyDisplayName
            description = "Disable insecure Windows Features and enable secure ones (Windows Sandbox, Hyper-V)"
            omaSettings = $omaSettings
        }

        $res = Invoke-IntuneGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations" -Body ($body | ConvertTo-Json -Depth 20)
        Write-Host "Created Optional Windows Features Policy: $($res.displayName) (id: $($res.id))" -ForegroundColor Green
        Write-Host "`nNote: Some features require PowerShell scripts for full configuration" -ForegroundColor Yellow
        Write-Host "Use Intune Scripts for: VBSCRIPT, WMIC, WordPad, PowerShell ISE, Steps Recorder removal" -ForegroundColor Gray
    }
    catch {
        Write-Error "Failed to create Optional Windows Features Policy: $_"
        if ($_.Exception.Response) {
            $reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
            $responseBody = $reader.ReadToEnd()
            Write-Host "Response: $responseBody" -ForegroundColor Red
        }
    }
}