Param( [Parameter(Mandatory=$true)] [string]$SiteRoot, [Parameter(Mandatory=$true)] [string]$BaseUrl, [string[]]$Extensions = @('.html', '.htm', '.php', '.asp', '.aspx'), [string]$OutputFile = "sitemap.xml", [ValidateSet('always','hourly','daily','weekly','monthly','yearly','never')] [string]$ChangeFreq = 'weekly', [ValidateRange(0.0,1.0)] [double]$Priority = 0.5 ) # Normalize inputs $SiteRoot = (Resolve-Path -Path $SiteRoot).ProviderPath if (-not $BaseUrl.EndsWith('/')) { $BaseUrl = "$BaseUrl/" } $OutputPath = Join-Path -Path $SiteRoot -ChildPath $OutputFile # Collect files $files = Get-ChildItem -Path $SiteRoot -Recurse -File | Where-Object { $Extensions -contains $_.Extension.ToLower() } # Setup XML writer $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true $settings.Encoding = [System.Text.Encoding]::UTF8 $writer = [System.Xml.XmlWriter]::Create($OutputPath, $settings) $writer.WriteStartDocument() $writer.WriteStartElement("urlset") $writer.WriteAttributeString("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9") foreach ($file in $files) { # Build relative URL $relativePath = $file.FullName.Substring($SiteRoot.Length).TrimStart('\','/') $relativePath = $relativePath -replace '\\','/' $loc = $BaseUrl + $relativePath # Escape characters per RFC 3986 $locEscaped = [System.Uri]::EscapeUriString($loc) $lastMod = $file.LastWriteTimeUtc.ToString("yyyy-MM-ddTHH:mm:sszzz") $writer.WriteStartElement("url") $writer.WriteElementString("loc", $locEscaped) $writer.WriteElementString("lastmod", $lastMod) $writer.WriteElementString("changefreq", $ChangeFreq) $writer.WriteElementString("priority", $Priority.ToString("0.0")) $writer.WriteEndElement() # url } $writer.WriteEndElement() # urlset $writer.WriteEndDocument() $writer.Flush() $writer.Close() Write-Host "Sitemap generated at: $OutputPath"