Credential Management
- Never hardcode passwords in scripts — use Windows Credential Manager:
```powershell
# Store
cmdkey /generic:"MyService" /user:"admin" /pass:"secret"
# Retrieve in script
$cred = Get-StoredCredential -Target "MyService"
```
- For scripts, use
Get-Credential and export securely:
```powershell
$cred | Export-Clixml -Path "cred.xml" # Encrypted to current user/machine
$cred = Import-Clixml -Path "cred.xml"
```
Silent Failures
- Windows Defender silently quarantines downloaded scripts/executables — check quarantine if script disappears
- Group Policy overrides local settings silently —
gpresult /r to see what's actually applied - Antivirus real-time scanning blocks file operations intermittently — add exclusions for build/automation folders
- PowerShell
-ErrorAction SilentlyContinue hides problems — use Stop and handle explicitly
Symbolic Links
- Creating symlinks requires admin OR SeCreateSymbolicLinkPrivilege — regular users fail silently
- Enable Developer Mode for symlinks without admin: Settings → For Developers → Developer Mode
mklink is CMD-only, PowerShell uses New-Item -ItemType SymbolicLink
Script Signing
- Unsigned scripts fail on restricted machines with confusing errors — sign for production:
```powershell
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert
Set-AuthenticodeSignature -FilePath script.ps1 -Certificate $cert
```
- AllSigned policy requires ALL scripts signed including profile.ps1
Operational Safety
- Always
-WhatIf first on destructive operations — Remove-Item -Recurse -WhatIf Start-Transcript for audit trail — forgotten until incident investigation- NTFS permissions:
icacls for CLI, but inheritance rules are non-obvious — test changes on copy first
WinRM Remoting
- Enable correctly:
Enable-PSRemoting -Force isn't enough on workgroups - Workgroup machines need TrustedHosts:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "server1,server2" - HTTPS remoting needs certificate setup — HTTP sends credentials readable on network
Event Logging
- Scripts should log to Windows Event Log for centralized monitoring:
```powershell
New-EventLog -LogName Application -Source "MyScript" -ErrorAction SilentlyContinue
Write-EventLog -LogName Application -Source "MyScript" -EventId 1000 -Message "Started"
```
- Custom event sources require admin to create — create during install, not runtime
File Locking
- Windows locks files aggressively — test file access before operations:
```powershell
try { [IO.File]::OpenWrite($path).Close(); $true } catch { $false }
```
- Scheduled tasks writing to same file as user → conflicts. Use unique temp files and atomic rename
Temp File Hygiene
$env:TEMP fills silently — scripts should cleanup with try/finally:
```powershell
$tmp = New-TemporaryFile
try { ... } finally { Remove-Item $tmp -Force }
```
- Orphaned temp files accumulate across reboots — unlike Linux /tmp
Service Account Gotchas
- Services run in different user context —
$env:USERPROFILE points to system profile, not user's - Network access from SYSTEM account uses machine credentials — may fail where user succeeds
- Mapped drives don't exist for services — use UNC paths
\\server\share