ScriptModification/Remove-Comments.ps1
function Remove-Comments { <# .SYNOPSIS Strips comments and extra whitespace from a script. PowerSploit Function: Remove-Comments Author: Matthew Graeber (@mattifestation) License: BSD 3-Clause Required Dependencies: None Optional Dependencies: None .DESCRIPTION Remove-Comments strips out comments and unnecessary whitespace from a script. This is best used in conjunction with Out-EncodedCommand when the size of the script to be encoded might be too big. A major portion of this code was taken from the Lee Holmes' Show-ColorizedContent script. You rock, Lee! .PARAMETER ScriptBlock Specifies a scriptblock containing your script. .PARAMETER Path Specifies the path to your script. .EXAMPLE C:\PS> $Stripped = Remove-Comments -Path .\ScriptWithComments.ps1 .EXAMPLE C:\PS> Remove-Comments -ScriptBlock { ### This is my awesome script. My documentation is beyond reproach! Write-Host 'Hello, World!' ### Write 'Hello, World' to the host ### End script awesomeness } Write-Host 'Hello, World!' .EXAMPLE C:\PS> Remove-Comments -Path Inject-Shellcode.ps1 | Out-EncodedCommand Description ----------- Removes extraneous whitespace and comments from Inject-Shellcode (which is notoriously large) and pipes the output to Out-EncodedCommand. .INPUTS System.String, System.Management.Automation.ScriptBlock Accepts either a string containing the path to a script or a scriptblock. .OUTPUTS System.Management.Automation.ScriptBlock Remove-Comments returns a scriptblock. Call the ToString method to convert a scriptblock to a string, if desired. .LINK http://www.exploit-monday.com http://www.leeholmes.com/blog/2007/11/07/syntax-highlighting-in-powershell/ #> [CmdletBinding( DefaultParameterSetName = 'FilePath' )] Param ( [Parameter(Position = 0, Mandatory = $True, ParameterSetName = 'FilePath' )] [ValidateNotNullOrEmpty()] [String] $Path, [Parameter(Position = 0, ValueFromPipeline = $True, Mandatory = $True, ParameterSetName = 'ScriptBlock' )] [ValidateNotNullOrEmpty()] [ScriptBlock] $ScriptBlock ) Set-StrictMode -Version 2 if ($PSBoundParameters['Path']) { Get-ChildItem $Path -ErrorAction Stop | Out-Null $ScriptBlockString = [IO.File]::ReadAllText((Resolve-Path $Path)) $ScriptBlock = [ScriptBlock]::Create($ScriptBlockString) } else { # Convert the scriptblock to a string so that it can be referenced with array notation $ScriptBlockString = $ScriptBlock.ToString() } # Tokenize the scriptblock and return all tokens except for comments $Tokens = [System.Management.Automation.PSParser]::Tokenize($ScriptBlock, [Ref] $Null) | Where-Object { $_.Type -ne 'Comment' } $StringBuilder = New-Object Text.StringBuilder # The majority of the remaining code comes from Lee Holmes' Show-ColorizedContent script. $CurrentColumn = 1 $NewlineCount = 0 foreach($CurrentToken in $Tokens) { # Now output the token if(($CurrentToken.Type -eq 'NewLine') -or ($CurrentToken.Type -eq 'LineContinuation')) { $CurrentColumn = 1 # Only insert a single newline. Sequential newlines are ignored in order to save space. if ($NewlineCount -eq 0) { $StringBuilder.AppendLine() | Out-Null } $NewlineCount++ } else { $NewlineCount = 0 # Do any indenting if($CurrentColumn -lt $CurrentToken.StartColumn) { # Insert a single space in between tokens on the same line. Extraneous whiltespace is ignored. if ($CurrentColumn -ne 1) { $StringBuilder.Append(' ') | Out-Null } } # See where the token ends $CurrentTokenEnd = $CurrentToken.Start + $CurrentToken.Length - 1 # Handle the line numbering for multi-line strings if(($CurrentToken.Type -eq 'String') -and ($CurrentToken.EndLine -gt $CurrentToken.StartLine)) { $LineCounter = $CurrentToken.StartLine $StringLines = $(-join $ScriptBlockString[$CurrentToken.Start..$CurrentTokenEnd] -split '`r`n') foreach($StringLine in $StringLines) { $StringBuilder.Append($StringLine) | Out-Null $LineCounter++ } } # Write out a regular token else { $StringBuilder.Append((-join $ScriptBlockString[$CurrentToken.Start..$CurrentTokenEnd])) | Out-Null } # Update our position in the column $CurrentColumn = $CurrentToken.EndColumn } } Write-Output ([ScriptBlock]::Create($StringBuilder.ToString())) } |