Start-SkatterTools.ps1
# Copyright (C) 2014 Yusuf Ozturk # Update/Modified/Ruined by David M. Stein (c) 2019 based on Start-PoSHServer # This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA function Start-SkatterTools { <# .SYNOPSIS Powershell Web Server Console application for viewing and managing Active Directory and System Center Configuration Manager. Built with PoSHServer. .DESCRIPTION Listens a port to serve web content. Supports HTML and Powershell. .PARAMETER WhatIf Display what would happen if you would run the function with given parameters. .PARAMETER Confirm Prompts for confirmation for each operation. Allow user to specify Yes/No to all option to stop prompting. .EXAMPLE Start-PoSHServer -IP 127.0.0.1 -Port 8080 .EXAMPLE Start-PoSHServer -Hostname "poshserver.net" -Port 8080 .EXAMPLE Start-PoSHServer -Hostname "poshserver.net" -Port 8080 -asJob .EXAMPLE Start-PoSHServer -Hostname "poshserver.net" -Port 8080 -SSL -SSLPort 8443 -asJob .EXAMPLE Start-PoSHServer -Hostname "poshserver.net" -Port 8080 -SSL -SSLIP "127.0.0.1" -SSLPort 8443 -asJob .EXAMPLE Start-PoSHServer -Hostname "poshserver.net" -Port 8080 -DebugMode .EXAMPLE Start-PoSHServer -Hostname "poshserver.net,www.poshserver.net" -Port 8080 .EXAMPLE Start-PoSHServer -Hostname "poshserver.net,www.poshserver.net" -Port 8080 -HomeDirectory "C:\inetpub\wwwroot" .EXAMPLE Start-PoSHServer -Hostname "poshserver.net,www.poshserver.net" -Port 8080 -HomeDirectory "C:\inetpub\wwwroot" -LogDirectory "C:\inetpub\wwwroot" .EXAMPLE Start-PoSHServer -Hostname "poshserver.net" -Port 8080 -CustomConfig "C:\inetpub\config.ps1" -CustomJob "C:\inetpub\job.ps1" .INPUTS None .OUTPUTS None .NOTES sktools by David M. Stein / skatterbrainz website: https://github.com/SkatterBrainz/sktools poshserver 3.7 by Yusuf Ozturk Website: http://www.yusufozturk.info Email: yusuf.ozturk@outlook.com Date created: 09-Oct-2011 Last modified: 07-Apr-2014 .LINK https://github.com/SkatterBrainz/sktools http://www.poshserver.net #> [CmdletBinding(SupportsShouldProcess = $true)] param ( # Hostname [Parameter(Mandatory = $false, HelpMessage = 'IP Address or Hostname')] [Alias('IP')] [string]$Hostname, # Port Number [Parameter(Mandatory = $false, HelpMessage = 'Port Number')] [string]$Port, # SSL IP Address [Parameter(Mandatory = $false, HelpMessage = 'SSL IP Address')] [string]$SSLIP, # SSL Port Number [Parameter(Mandatory = $false, HelpMessage = 'SSL Port Number')] [string]$SSLPort, # SSL Port Number [Parameter(Mandatory = $false, HelpMessage = 'SSL Friendly Name. Example: poshserver.net')] [string]$SSLName, # Home Directory [Parameter(Mandatory = $false, HelpMessage = 'Home Directory. Example: C:\inetpub\wwwroot')] [string]$HomeDirectory = "$PSScriptRoot\webui", # Log Directory [Parameter(Mandatory = $false, HelpMessage = 'Log Directory. Example: C:\inetpub\wwwroot')] [string]$LogDirectory, # Custom Config Path [Parameter(Mandatory = $false, HelpMessage = 'Custom Config Path. Example: C:\inetpub\config.ps1')] [string]$CustomConfig, # Custom Child Config Path [Parameter(Mandatory = $false, HelpMessage = 'Custom Child Config Path. Example: C:\inetpub\childconfig.ps1')] [string]$CustomChildConfig, # Custom Job Path [Parameter(Mandatory = $false, HelpMessage = 'Custom Job Path. Example: C:\inetpub\jobs.ps1')] [string] $CustomJob, # Custom Job Schedule [Parameter(Mandatory = $false, HelpMessage = 'Custom Job Schedule. Example: 1, 5, 10, 20, 30, 60')] [ValidateSet("1","5","10","20","30","60")] [string] $CustomJobSchedule = "5", # Background Job ID [Parameter(Mandatory = $false, HelpMessage = 'Background Job ID. Example: 52341')] [string] $JobID, # Background Job Username [Parameter(Mandatory = $false, HelpMessage = 'Background Job Username. Example: CONTOSO\Administrator')] [string] $JobUsername, # Background Job User Password [Parameter(Mandatory = $false, HelpMessage = 'Background Job User Password. Example: P@ssw0rd1')] [string] $JobPassword, # Background Job Credentials [Parameter(Mandatory = $false, HelpMessage = 'Run Background Job as Different User')] [switch] $JobCredentials = $false, # Enable SSL [Parameter(Mandatory = $false, HelpMessage = 'Enable SSL')] [switch] $SSL = $false, # Debug Mode [Parameter(Mandatory = $false, HelpMessage = 'Debug Mode')] [switch]$DebugMode = $false, # Background Job [Parameter(Mandatory = $false, HelpMessage = 'Run As Background Job')] [switch]$asJob = $false ) # Enable Debug Mode if ($DebugMode){ $DebugPreference = "Continue" } else{ $ErrorActionPreference = "silentlycontinue" } # Get PoSH Server Path $PoSHServerPath = "$PSScriptRoot" # Get PoSH Server Module Path $PoSHModulePath = "$PSScriptRoot\modules" Write-Verbose "poshserver module path: $PoSHModulePath" # Test PoSH Server Module Path $PoSHModulePathTest = Test-Path $PoSHModulePath if (!$PoSHModulePathTest){ Write-Warning "Could not detect PoSH Server Module Path." Write-Warning "Aborting.." $ResultCode = "-1" $ResultMessage = "Could not detect PoSH Server Module Path." } else{ # Import Functions . $PoSHModulePath\functions.ps1 } # Background Job Control if ($asJob -and $ResultCode -ne "-1"){ if ($JobCredentials){ Write-Host " " Write-Host "Please specify user credentials for PoSH Server background job." Write-Host " " $JobUsername = Read-Host -Prompt "Username" $JobSecurePassword = Read-Host -Prompt "Password" -AsSecureString $JobSecureCredentials = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList $JobUsername,$JobSecurePassword $JobPassword = $JobSecureCredentials.GetNetworkCredential().Password } } # Background Job ID if ($JobID -and $ResultCode -ne "-1"){ $JobIDPath = "$PoSHServerPath\jobs\job-$JobID.txt" $TestJobID = Test-Path $JobIDPath if ($JobIDPath) { $JobIDContent = Get-Content $JobIDPath $Hostname = $JobIDContent.Split(";")[0] $Port = $JobIDContent.Split(";")[1] $SSLIP = $JobIDContent.Split(";")[2] $SSLPort = $JobIDContent.Split(";")[3] $SSLName = $JobIDContent.Split(";")[4] $HomeDirectory = $JobIDContent.Split(";")[5] $LogDirectory = $JobIDContent.Split(";")[6] $CustomConfig = $JobIDContent.Split(";")[7] $CustomChildConfig = $JobIDContent.Split(";")[8] $CustomJob = $JobIDContent.Split(";")[9] } else{ Write-Warning "Job ID is not exist." Write-Warning "Aborting.." $ResultCode = "-1" $ResultMessage = "Job ID is not exist." } } if ($ResultCode -ne "-1"){ # Get Home and Log Directories if (!$HomeDirectory) { $HomeDirectory = "$PoSHServerPath\webroot\http" } if (!$LogDirectory) { $LogDirectory = "$PoSHServerPath\webroot\logs" } # Admin Privileges Verification . $PoSHModulePath\adminverification.ps1 # Server IP Verification . $PoSHModulePath\ipverification.ps1 # PHP Encoding Module . $PoSHModulePath\phpencoding.ps1 # Break Script If Something's Wrong if ($ShouldProcess -eq $false){ $ResultCode = "-1" $ResultMessage = "Please check module output." } } if ($ResultCode -ne "-1"){ # Enable Background Job if ($asJob) { if (!$Hostname) { $Hostname = "+" $TaskHostname = "localhost" } else{ $TaskHostname = $Hostname.Split(",")[0] } if (!$Port) { $Port = "8080" $TaskPort = "8080" } else{ $TaskPort = $Port.Split(",")[0] } if ($SSL){ if (!$SSLIP) { $SSLIP = "127.0.0.1" if (!$SSLPort){ $SSLPort = "8443" } } } $CheckTask = schtasks.exe | where {$_ -like "PoSHServer-$TaskHostname-$TaskPort*"} if ($CheckTask){ Write-Warning "This job is already exist. You should run it from Scheduled Jobs." Write-Warning "Aborting.." $ResultCode = "-1" $ResultMessage = "This job is already exist. You should run it from Scheduled Jobs." } else{ # Prepare Job Information $TaskID = Get-Random -Maximum 10000 $TaskName = "PoSHServer-$TaskHostname-$TaskPort-$TaskID" $CreateJobIDPath = $PoSHServerPath + "\jobs\job-" + $TaskID + ".txt" $CreateJobIDValue = $Hostname + ";" + $Port + ";" + $SSLIP + ";" + $SSLPort + ";" + $SSLName + ";" + $HomeDirectory + ";" + $LogDirectory + ";" + $CustomConfig + ";" + $CustomChildConfig + ";" + $CustomJob $CreateJobID = Add-Content -Path $CreateJobIDPath -Value $CreateJobIDValue # Create Scheduled Jobs $CreateTask = schtasks /create /tn "$TaskName" /xml "$PoSHServerPath\jobs\template.xml" /ru SYSTEM $ChangeTaskProcess = $true while ($ChangeTaskProcess) { if ($SSL){ $ChangeTask = schtasks /change /tn "$TaskName" /tr "Powershell -Command &{Import-Module PoSHServer; Start-PoSHServer -SSL -JobID $TaskID}" /rl highest } else{ $ChangeTask = schtasks /change /tn "$TaskName" /tr "Powershell -Command &{Import-Module PoSHServer; Start-PoSHServer -JobID $TaskID}" /rl highest } if ($ChangeTask){ $ChangeTaskProcess = $false } } if ($JobUsername -and $JobPassword){ $ChangeTaskProcess = $true while ($ChangeTaskProcess){ $ChangeTask = schtasks /tn "$TaskName" /Change /RU "$JobUsername" /RP "$JobPassword" if ($ChangeTask){ $ChangeTaskProcess = $false } } } # Start Background Job $RunTask = schtasks /run /tn "$TaskName" # PoSH Server Welcome Banner Get-PoSHWelcomeBanner -Hostname $Hostname -Port $Port -SSL $SSL -SSLIP $SSLIP -SSLPort $SSLPort -DebugMode $DebugMode } } else { # PoSH Server Scheduled Background Jobs $PoSHJobArgs = @($Hostname,$Port,$HomeDirectory,$LogDirectory,$PoSHModulePath,$asJob) $PoSHJob = Start-Job -ScriptBlock { param ($Hostname, $Port, $HomeDirectory, $LogDirectory, $PoSHModulePath, $asJob) # Import Functions . $PoSHModulePath\functions.ps1 # PoSH Server Custom Configuration $PoSHCustomConfigPath = $HomeDirectory + "\config.ps1" # Test Config Path $TestPoSHCustomConfigPath = Test-Path $PoSHCustomConfigPath if (!$TestPoSHCustomConfigPath) { # Import Config . $PoSHModulePath\config.ps1 } else{ # Import Config . $HomeDirectory\config.ps1 } while ($true){ Start-Sleep -s 60 # Get Job Time $JobTime = Get-Date -format HHmm if ($LogSchedule -eq "Hourly"){ # PoSH Server Log Hashing (at *:30 hourly) if ($JobTime -eq "*30") { New-PoSHLogHash -LogSchedule $LogSchedule -LogDirectory $LogDirectory } } else{ # PoSH Server Log Hashing (at 02:30 daily) if ($JobTime -eq "0230") { New-PoSHLogHash -LogSchedule $LogSchedule -LogDirectory $LogDirectory } } } } -ArgumentList $PoSHJobArgs # PoSH Server Custom Background Jobs $PoSHCustomJobArgs = @($Hostname,$Port,$HomeDirectory,$LogDirectory,$PoSHModulePath,$CustomJob,$CustomJobSchedule,$asJob) $PoSHCustomJob = Start-Job -scriptblock { param ($Hostname, $Port, $HomeDirectory, $LogDirectory, $PoSHModulePath, $CustomJob, $CustomJobSchedule, $asJob) # Import Functions . $PoSHModulePath\functions.ps1 # PoSH Server Custom Configuration $PoSHCustomConfigPath = $HomeDirectory + "\config.ps1" # Test Config Path $TestPoSHCustomConfigPath = Test-Path $PoSHCustomConfigPath if (!$TestPoSHCustomConfigPath) { # Import Config . $PoSHModulePath\config.ps1 } else{ # Import Config . $HomeDirectory\config.ps1 } while ($true){ Start-Sleep -s 60 # Get Job Time $JobTime = Get-Date -format HHmm if ($CustomJobSchedule -eq "1") { # PoSH Server Custom Jobs (at every 1 minute) if ($CustomJob) { . $CustomJob } } elseif ($CustomJobSchedule -eq "5") { # PoSH Server Custom Jobs (at every 5 minutes) if ($JobTime -like "*5" -or $JobTime -like "*0"){ if ($CustomJob) { . $CustomJob } } } elseif ($CustomJobSchedule -eq "10"){ # PoSH Server Custom Jobs (at every 10 minutes) if ($JobTime -like "*00" -or $JobTime -like "*10" -or $JobTime -like "*20" -or $JobTime -like "*30" -or $JobTime -like "*40" -or $JobTime -like "*50") { if ($CustomJob){ . $CustomJob } } } elseif ($CustomJobSchedule -eq "20"){ # PoSH Server Custom Jobs (at every 20 minutes) if ($JobTime -like "*00" -or $JobTime -like "*20" -or $JobTime -like "*40") { if ($CustomJob) { . $CustomJob } } } elseif ($CustomJobSchedule -eq "30"){ # PoSH Server Custom Jobs (at every 30 minutes) if ($JobTime -like "*00" -or $JobTime -like "*30"){ if ($CustomJob){ . $CustomJob } } } elseif ($CustomJobSchedule -eq "60"){ # PoSH Server Custom Jobs (at every hour) if ($JobTime -like "*00"){ if ($CustomJob){ . $CustomJob } } } else{ # PoSH Server Custom Jobs (at every 5 minutes) if ($JobTime -like "*5" -or $JobTime -like "*0"){ if ($CustomJob) { . $CustomJob } } } } } -ArgumentList $PoSHCustomJobArgs # PoSH Server Custom Config if ($CustomConfig){ . $CustomConfig } # Create an HTTPListener try{ $Listener = New-Object Net.HttpListener } catch{ Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } # Add Prefix Urls try { if (!$Hostname) { $Hostname = "+" if (!$Port) { $Port = "8080" } $Prefix = "http://" + $Hostname + ":" + $Port + "/" $Listener.Prefixes.Add($Prefix) } else{ $Hostnames = @($Hostname.Split(",")) if (!$Port) { $Port = "8080" } foreach ($Hostname in $Hostnames){ $Prefix = "http://" + $Hostname + ":" + $Port + "/" $Listener.Prefixes.Add($Prefix) } } if ($SSL){ if (!$SSLIP) { $SSLIP = "127.0.0.1" if (!$SSLPort){ $SSLPort = "8443" } $Prefix = "https://" + $SSLIP + ":" + $SSLPort + "/" $Listener.Prefixes.Add($Prefix) } else{ $SSLIPAddresses = @($SSLIP.Split(",")) if (!$SSLPort){ $SSLPort = "8443" } foreach ($SSLIPAddress in $SSLIPAddresses){ $Prefix = "https://" + $SSLIPAddress + ":" + $SSLPort + "/" $Listener.Prefixes.Add($Prefix) } } } } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } # Start Listener try { $Listener.Start() } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } # Configure SSL try { if ($SSL) { if ($SSLName) { $PoSHCert = Get-ChildItem -Recurse Cert: | Where-Object { $_.FriendlyName -eq $SSLName } if (!$PoSHCert) { $PoSHCert = Get-ChildItem -Recurse Cert: | Where-Object { $_.FriendlyName -eq "PoSHServer SSL Certificate" } } } else { $PoSHCert = Get-ChildItem -Recurse Cert: | Where-Object { $_.FriendlyName -eq "PoSHServer SSL Certificate" } } if (!$PoSHCert) { if ($DebugMode) { Add-Content -Value "Sorry, I couldn't find your SSL certificate." -Path "$LogDirectory\debug.txt" Add-Content -Value "Creating Self-Signed SSL certificate.." -Path "$LogDirectory\debug.txt" } Request-PoSHCertificate $PoSHCert = Get-ChildItem -Recurse Cert: | Where-Object { $_.FriendlyName -eq "PoSHServer SSL Certificate" } } # Register SSL Certificate $CertThumbprint = $PoSHCert[0].Thumbprint Register-PoSHCertificate -SSLIP $SSLIP -SSLPort $SSLPort -Thumbprint $CertThumbprint -DebugMode $DebugMode } } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } # PoSH Server Welcome Banner try { Get-PoSHWelcomeBanner -Hostname $Hostname -Port $Port -SSL $SSL -SSLIP $SSLIP -SSLPort $SSLPort -DebugMode $DebugMode } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } # PoSH Server Async Process Script $ScriptBlock = ` { Param($Listener, $Hostname, $Hostnames, $HomeDirectory, $LogDirectory, $PoSHModulePath, $CustomChildConfig, $DebugMode) # Import Functions . $PoSHModulePath\functions.ps1 # Enable Debug Mode if ($DebugMode) { $DebugPreference = "Continue" } else { $ErrorActionPreference = "silentlycontinue" } # PHP Encoding Module . $PoSHModulePath\phpencoding.ps1 # PoSH Server Custom Child Config if ($CustomChildConfig) { . $CustomChildConfig } # Create loop $ShouldProcess = $true # Get Server Requests while ($ShouldProcess) { # PoSH Server Custom Configuration $PoSHCustomConfigPath = $HomeDirectory + "\config.ps1" # Test Config Path $TestPoSHCustomConfigPath = Test-Path $PoSHCustomConfigPath if (!$TestPoSHCustomConfigPath) { # Import Config . $PoSHModulePath\config.ps1 } else { # Import Config . $HomeDirectory\config.ps1 } # Reset Authentication $Listener.AuthenticationSchemes = "Anonymous"; # Set Authentication if ($BasicAuthentication -eq "On") { $Listener.AuthenticationSchemes = "Basic"; } if ($NTLMAuthentication -eq "On") { $Listener.AuthenticationSchemes = "NTLM"; } if ($WindowsAuthentication -eq "On") { $Listener.AuthenticationSchemes = "IntegratedWindowsAuthentication"; } # Open Connection $Context = $Listener.GetContext() # Authentication Module . $PoSHModulePath\authentication.ps1 # Set Home Directory [IO.Directory]::SetCurrentDirectory("$HomeDirectory") $File = $Context.Request.Url.LocalPath $Response = $Context.Response $Response.Headers.Add("Accept-Encoding","gzip"); $Response.Headers.Add("Server","PoSH Server"); $Response.Headers.Add("X-Powered-By","Microsoft PowerShell"); # Set Request Parameters $Request = $Context.Request $InputStream = $Request.InputStream $ContentEncoding = $Request.ContentEncoding # IP Restriction Module . $PoSHModulePath\iprestriction.ps1 # Get Query String $PoSHQuery = Get-PoSHQueryString -Request $Request # Get Post Stream $PoSHPost = Get-PoSHPostStream -InputStream $InputStream -ContentEncoding $ContentEncoding # Cookie Information $PoSHCookies = $Request.Cookies["PoSHSessionID"]; if (!$PoSHCookies) { $PoSHCookie = New-Object Net.Cookie $PoSHCookie.Name = "PoSHSessionID" $PoSHCookie.Value = New-PoSHTimeStamp $Response.AppendCookie($PoSHCookie) } # Get Default Document if ($File -notlike "*.*" -and $File -like "*/") { $FolderPath = [System.IO.Directory]::GetCurrentDirectory() + $File $RequstURL = [string]$Request.Url $SubfolderName = $File $File = $File + $DefaultDocument } elseif ($File -notlike "*.*" -and $File -notlike "*/") { $FolderPath = [System.IO.Directory]::GetCurrentDirectory() + $File + "/" $RequstURL = [string]$Request.Url + "/" $SubfolderName = $File + "/" $File = $File + "/" + $DefaultDocument } else { $FolderPath = $Null; } # PoSH API Support if ($File -like "*.psxml") { $File = $File.Replace(".psxml",".ps1") # Full File Path $File = [System.IO.Directory]::GetCurrentDirectory() + $File # Get Mime Type $MimeType = "text/psxml" } else { # Full File Path $File = [System.IO.Directory]::GetCurrentDirectory() + $File # Get Mime Type $FileExtension = (Get-ChildItem $File -EA SilentlyContinue).Extension $MimeType = Get-MimeType $FileExtension } # Content Filtering Module . $PoSHModulePath\contentfiltering.ps1 # Stream Content if ([System.IO.File]::Exists($File) -and $ContentSessionDrop -eq "0" -and $IPSessionDrop -eq "0") { if ($MimeType -eq "text/ps1") { try { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $File)") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } elseif ($MimeType -eq "text/psxml") { try { $Response.ContentType = "text/xml" $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $File)") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } elseif ($MimeType -eq "text/php") { try { if ($PHPCgiPath) { $TestPHPCgiPath = Test-Path -Path $PHPCgiPath } else { $TestPHPCgiPath = $false } if ($TestPHPCgiPath) { if ($File -like "C:\Windows\*") { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::NotFound $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $PoSHModulePath\phpsecurityerror.ps1)") } else { $Response.ContentType = "text/html" $PHPContentOutput = Get-PoSHPHPContent -PHPCgiPath "$PHPCgiPath" -File "$File" -PoSHPHPGET $PoSHQuery.PoSHQueryString -PoSHPHPPOST $PoSHPost.PoSHPostStream $PHPContentOutput = Set-PHPEncoding -PHPOutput $PHPContentOutput $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$PHPContentOutput") } } else { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::NotFound $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $PoSHModulePath\phpcgierror.ps1)") } } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } else { try { $Response.ContentType = "$MimeType" $FileContent = [System.IO.File]::ReadAllBytes($File) $Response.ContentLength64 = $FileContent.Length $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response.OutputStream.Write($FileContent, 0, $FileContent.Length) } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } } else { # Content Filtering and IP Restriction Control if ($ContentSessionDrop -eq "0" -and $IPSessionDrop -eq "0") { if ($FolderPath) { $TestFolderPath = Test-Path -Path $FolderPath } else { $TestFolderPath = $false } } else { $TestFolderPath = $false } if ($DirectoryBrowsing -eq "On" -and $TestFolderPath) { try { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) if ($Hostname -eq "+") { $HeaderName = "localhost" } else { $HeaderName = $Hostnames[0] } $DirectoryContent = (Get-DirectoryContent -Path "$FolderPath" -HeaderName $HeaderName -RequestURL $RequestURL -SubfolderName $SubfolderName) $Response.WriteLine("$DirectoryContent") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } else { try { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::NotFound $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $PoSHModulePath\notfound.ps1)") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } } # Logging Module . $PoSHModulePath\log.ps1 # Close Connection try { $Response.Close() } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } } if ($DebugMode) { # Invoke PoSH Server Multithread Process - Thread 1 Invoke-AsyncHTTPRequest -ScriptBlock $ScriptBlock -Listener $Listener -Hostname $Hostname -Hostnames $Hostnames -HomeDirectory $HomeDirectory -LogDirectory $LogDirectory -PoSHModulePath $PoSHModulePath -CustomChildConfig $CustomChildConfig -DebugMode | Out-Null # Invoke PoSH Server Multithread Process - Thread 2 Invoke-AsyncHTTPRequest -ScriptBlock $ScriptBlock -Listener $Listener -Hostname $Hostname -Hostnames $Hostnames -HomeDirectory $HomeDirectory -LogDirectory $LogDirectory -PoSHModulePath $PoSHModulePath -CustomChildConfig $CustomChildConfig -DebugMode | Out-Null # Invoke PoSH Server Multithread Process - Thread 3 Invoke-AsyncHTTPRequest -ScriptBlock $ScriptBlock -Listener $Listener -Hostname $Hostname -Hostnames $Hostnames -HomeDirectory $HomeDirectory -LogDirectory $LogDirectory -PoSHModulePath $PoSHModulePath -CustomChildConfig $CustomChildConfig -DebugMode | Out-Null } else { # Invoke PoSH Server Multithread Process - Thread 1 Invoke-AsyncHTTPRequest -ScriptBlock $ScriptBlock -Listener $Listener -Hostname $Hostname -Hostnames $Hostnames -HomeDirectory $HomeDirectory -LogDirectory $LogDirectory -PoSHModulePath $PoSHModulePath -CustomChildConfig $CustomChildConfig | Out-Null # Invoke PoSH Server Multithread Process - Thread 2 Invoke-AsyncHTTPRequest -ScriptBlock $ScriptBlock -Listener $Listener -Hostname $Hostname -Hostnames $Hostnames -HomeDirectory $HomeDirectory -LogDirectory $LogDirectory -PoSHModulePath $PoSHModulePath -CustomChildConfig $CustomChildConfig | Out-Null # Invoke PoSH Server Multithread Process - Thread 3 Invoke-AsyncHTTPRequest -ScriptBlock $ScriptBlock -Listener $Listener -Hostname $Hostname -Hostnames $Hostnames -HomeDirectory $HomeDirectory -LogDirectory $LogDirectory -PoSHModulePath $PoSHModulePath -CustomChildConfig $CustomChildConfig | Out-Null } # Create loop $ShouldProcess = $true # Get Server Requests while ($ShouldProcess) { # PoSH Server Custom Configuration $PoSHCustomConfigPath = $HomeDirectory + "\config.ps1" # Test Config Path $TestPoSHCustomConfigPath = Test-Path $PoSHCustomConfigPath if (!$TestPoSHCustomConfigPath) { # Import Config . $PoSHModulePath\config.ps1 } else { # Import Config . $HomeDirectory\config.ps1 } # Reset Authentication $Listener.AuthenticationSchemes = "Anonymous"; # Set Authentication if ($BasicAuthentication -eq "On") { $Listener.AuthenticationSchemes = "Basic"; } if ($NTLMAuthentication -eq "On") { $Listener.AuthenticationSchemes = "NTLM"; } if ($WindowsAuthentication -eq "On") { $Listener.AuthenticationSchemes = "IntegratedWindowsAuthentication"; } # Open Connection $Context = $Listener.GetContext() # Authentication Module . $PoSHModulePath\authentication.ps1 # Set Home Directory [IO.Directory]::SetCurrentDirectory("$HomeDirectory") $File = $Context.Request.Url.LocalPath $Response = $Context.Response $Response.Headers.Add("Accept-Encoding","gzip"); $Response.Headers.Add("Server","PoSH Server"); $Response.Headers.Add("X-Powered-By","Microsoft PowerShell"); # Set Request Parameters $Request = $Context.Request $InputStream = $Request.InputStream $ContentEncoding = $Request.ContentEncoding # IP Restriction Module . $PoSHModulePath\iprestriction.ps1 # Get Query String $PoSHQuery = Get-PoSHQueryString -Request $Request # Get Post Stream $PoSHPost = Get-PoSHPostStream -InputStream $InputStream -ContentEncoding $ContentEncoding # Cookie Information $PoSHCookies = $Request.Cookies["PoSHSessionID"]; if (!$PoSHCookies) { $PoSHCookie = New-Object Net.Cookie $PoSHCookie.Name = "PoSHSessionID" $PoSHCookie.Value = New-PoSHTimeStamp $Response.AppendCookie($PoSHCookie) } # Get Default Document if ($File -notlike "*.*" -and $File -like "*/") { $FolderPath = [System.IO.Directory]::GetCurrentDirectory() + $File $RequstURL = [string]$Request.Url $SubfolderName = $File $File = $File + $DefaultDocument } elseif ($File -notlike "*.*" -and $File -notlike "*/") { $FolderPath = [System.IO.Directory]::GetCurrentDirectory() + $File + "/" $RequstURL = [string]$Request.Url + "/" $SubfolderName = $File + "/" $File = $File + "/" + $DefaultDocument } else { $FolderPath = $Null; } # PoSH API Support if ($File -like "*.psxml") { $File = $File.Replace(".psxml",".ps1") # Full File Path $File = [System.IO.Directory]::GetCurrentDirectory() + $File # Get Mime Type $MimeType = "text/psxml" } else { # Full File Path $File = [System.IO.Directory]::GetCurrentDirectory() + $File # Get Mime Type $FileExtension = (Get-ChildItem $File -EA SilentlyContinue).Extension $MimeType = Get-MimeType $FileExtension } # Content Filtering Module . $PoSHModulePath\contentfiltering.ps1 # Stream Content if ([System.IO.File]::Exists($File) -and $ContentSessionDrop -eq "0" -and $IPSessionDrop -eq "0") { if ($MimeType -eq "text/ps1") { try { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $File)") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } elseif ($MimeType -eq "text/psxml") { try { $Response.ContentType = "text/xml" $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $File)") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } elseif ($MimeType -eq "text/php") { try { if ($PHPCgiPath) { $TestPHPCgiPath = Test-Path -Path $PHPCgiPath } else { $TestPHPCgiPath = $false } if ($TestPHPCgiPath) { if ($File -like "C:\Windows\*") { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::NotFound $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $PoSHModulePath\phpsecurityerror.ps1)") } else { $Response.ContentType = "text/html" $PHPContentOutput = Get-PoSHPHPContent -PHPCgiPath "$PHPCgiPath" -File "$File" -PoSHPHPGET $PoSHQuery.PoSHQueryString -PoSHPHPPOST $PoSHPost.PoSHPostStream $PHPContentOutput = Set-PHPEncoding -PHPOutput $PHPContentOutput $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$PHPContentOutput") } } else { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::NotFound $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $PoSHModulePath\phpcgierror.ps1)") } } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } else { try { $Response.ContentType = "$MimeType" $FileContent = [System.IO.File]::ReadAllBytes($File) $Response.ContentLength64 = $FileContent.Length $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response.OutputStream.Write($FileContent, 0, $FileContent.Length) } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } } else { # Content Filtering and IP Restriction Control if ($ContentSessionDrop -eq "0" -and $IPSessionDrop -eq "0") { if ($FolderPath) { $TestFolderPath = Test-Path -Path $FolderPath } else { $TestFolderPath = $false } } else { $TestFolderPath = $false } if ($DirectoryBrowsing -eq "On" -and $TestFolderPath) { try { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::OK $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) if ($Hostname -eq "+") { $HeaderName = "localhost" } else { $HeaderName = $Hostnames[0] } $DirectoryContent = (Get-DirectoryContent -Path "$FolderPath" -HeaderName $HeaderName -RequestURL $RequestURL -SubfolderName $SubfolderName) $Response.WriteLine("$DirectoryContent") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } else { try { $Response.ContentType = "text/html" $Response.StatusCode = [System.Net.HttpStatusCode]::NotFound $LogResponseStatus = $Response.StatusCode $Response = New-Object IO.StreamWriter($Response.OutputStream,[Text.Encoding]::UTF8) $Response.WriteLine("$(. $PoSHModulePath\notfound.ps1)") } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } } # Logging Module . $PoSHModulePath\log.ps1 # Close Connection try { $Response.Close() } catch { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" } } # Stop Listener $Listener.Stop() } } } Export-ModuleMember -Function Start-SkatterTools |