-
Notifications
You must be signed in to change notification settings - Fork 1
/
purify.ps1
164 lines (146 loc) · 5.53 KB
/
purify.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
[CmdLetBinding()]
Param(
[Parameter(Mandatory=$true,Position=0,ValueFromPipeLine=$true)]
[ValidateScript({ Test-Path "${_}" -PathType Container })]
[System.IO.DirectoryInfo[]] $source
,
[Parameter(Mandatory=$true,Position=1)]
[System.IO.DirectoryInfo] $dest_root
,
[Parameter(Mandatory=$false)]
[string] $strip_extension=".txt"
,
[Parameter(Mandatory=$false)]
[bool] $strip_firstline=$true
,
[Parameter(Mandatory=$false)]
[string[]] $strip_firstline_whitelist=@(
".png"
".jpg"
)
,
[Parameter(Mandatory=$false)]
[string[]] $decode_types=@(
".exe"
".rpm"
".msi"
".pdf"
".zip"
".class"
".jar"
".eps"
".tar"
".gz"
".mpp"
".sls"
".adml"
".admx"
".py"
".wsf"
".template"
".bundle"
)
,
[Parameter(Mandatory=$false)]
[switch] $force
)
BEGIN {
function Convert-StringToBinary {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,Position=0,ValueFromPipeLine=$true)]
[string] $InputString
,
[Parameter(Mandatory=$false)]
[string] $FilePath = ('{0}\{1}' -f $env:TEMP, [System.Guid]::NewGuid().ToString())
)
try
{
if ($InputString.Length -ge 1)
{
$ByteArray = [System.Convert]::FromBase64String($InputString);
[System.IO.File]::WriteAllBytes("${FilePath}", $ByteArray);
}
}
catch
{
throw ('Failed to create file from Base64 string: {0}' -f $FilePath);
}
Write-Output -InputObject (Get-Item -Path "${FilePath}");
}
#Make sure $dest_root exists and is a directory item
$dest_root = New-Item -Path $dest_root -ItemType Directory -Force
}
PROCESS {
foreach ($s_dir in $source) {
"Beginning to process source directory: `'$s_dir`'" | Out-Default
# Make sure the source is a directory item
if ( ($s_dir.gettype().name) -ne "DirectoryInfo" ) {
$s_dir = Get-Item $s_dir
}
# Construct the destination path
$dest = "${dest_root}\$(${s_dir}.name)"
# If the destination path exists, remove it
if (Test-Path $dest) {
if (-not $force) {
Write-Host "Destination path, `'$dest`', already exists and must be removed to continue." -ForegroundColor "Yellow"
Write-Host "Delete it now? Any response other than `'[Y]es`' will skip this directory. ( [Y]es | [N]o ): " -NoNewLine -ForegroundColor "Yellow"
$response = Read-Host
if ($response -notmatch "y|yes") {
Write-Host "Ok, will not delete `'$dest`'. Skipping this directory." -ForegroundColor "Red"
continue
}
}
" Deleting destination directory, `'$dest`'." | Out-Default
Remove-Item -Path $dest -Recurse -Force
}
# Create the target directory
" Creating the destination directory, `'${dest}`'." | Out-Default
$dest = New-Item -Path $dest -ItemType Directory -Force
# Create array of all subdirectories in the source excluding .git
$dirs = @(Get-ChildItem -Path $s_dir -Recurse | where { $_.FullName -notmatch "\.git$"} | where { $_.PSIsContainer -eq $true })
# Create the directory tree
" Replicating the directory tree of the source in the destination directory." | Out-Default
$new_dirs = $dirs | foreach {
New-Item -Path "${dest}\$(${_}.FullName.Substring($s_dir.FullName.length))" -ItemType "Directory" -Force
}
# Create array of all files that are not in the .git directory
$files = @(Get-ChildItem -Path $s_dir -Recurse | where { $_.FullName -notmatch "\.git$|\.git\\"} | where { $_.PSIsContainer -eq $false })
# Copy the files, removing the $strip_extension extension
" Copying files to the destination directory" | Out-Default
$new_files = $files | foreach {
$DestFileName = "${dest}\$(${_}.FullName.Substring($s_dir.FullName.length))"
if ( $DestFileName.ToLower().EndsWith($strip_extension) ) {
$DestFileName = $DestFileName.Substring(0,$DestFileName.Length-$strip_extension.Length)
}
Copy-Item -Path $_.FullName -Destination $DestFileName -Force -PassThru
}
# Strip the first line from each file
if ($strip_firstline) {
" Stripping first line from each file in the destination directory." | Out-Default
$new_files | where { $strip_firstline_whitelist -notcontains $_.Extension } | foreach {
# Courtesy http://stackoverflow.com/a/8852812
# Get the contents as a string
$contents = [IO.File]::ReadAllText($_)
# Check for unix line endings
# Courtesy http://www.computing.net/answers/programming/batch-to-detect-unix-and-windows-line-endings/24948.html
$EOL = "`r`n"
if ( $contents -Match "[^`r]`n" ) { $EOL = "`n" }
# Strip the first line
$contents = $contents -replace "^.*$EOL", ""
# Create UTF-8 encoding without signature
$utf8 = New-Object System.Text.UTF8Encoding $false
# Write the text back
[IO.File]::WriteAllText($_, $contents, $utf8)
}
}
# Decode base64 content for files with extensions that match $decode_types
" Decoding base64-encoded files..."
$null = $new_files | where { $decode_types -contains $_.Extension -or $_.Extension -match "[0-9]{3}" } | foreach {
(Get-Content $_.FullName) | Convert-StringToBinary -FilePath $_.FullName
}
}
}
END {
"Completed processing all directories." | Out-Default
}