Skip to content

Commit

Permalink
Updating Get-ChildItem calls to use the -Force.
Browse files Browse the repository at this point in the history
  • Loading branch information
davehull committed Sep 12, 2015
1 parent 8e207f1 commit 6def92e
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Analysis/Get-LogparserStack.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Param(
)
Write-Verbose ("{0}: Building list of files matching {1}." -f (GetTimeStampUtc), $FilePattern)
$Files = @()
$Files += (Get-ChildItem *$FilePattern*)
$Files += (Get-ChildItem -Force *$FilePattern*)
$Files
}

Expand Down
2 changes: 1 addition & 1 deletion Modules/ASEP/Get-AutorunscDeep.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Param(
}

if (Test-Path $FilePath) {
$File = Get-ChildItem $FilePath
$File = Get-ChildItem -Force $FilePath
$fileData = [System.IO.File]::ReadAllBytes($File.FullName)
$HashBytes = $hash.ComputeHash($fileData)
$PaddedHex = ""
Expand Down
2 changes: 1 addition & 1 deletion Modules/Config/Get-PSDotNetVersion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ foreach($item in $PSVersionTable.Keys) {
}

$i = 1
Get-ChildItem "$($env:windir)\Microsoft.Net\Framework" -Include mscorlib.dll -Recurse | ForEach-Object {
Get-ChildItem -Force "$($env:windir)\Microsoft.Net\Framework" -Include mscorlib.dll -Recurse | ForEach-Object {
$obj | Add-Member NoteProperty .NET_$i $_.VersionInfo.ProductVersion
$i++
}
Expand Down
4 changes: 2 additions & 2 deletions Modules/Disk/Get-FileHashes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ workflow Get-HashesWorkflow {
$hashList = @()

$Files = (
Get-ChildItem -Path $basePath -Recurse -Force -ErrorAction SilentlyContinue |
Get-ChildItem -Force -Path $basePath -Recurse -Force -ErrorAction SilentlyContinue |
? -FilterScript {
($_.Length -ge $MinB -and $_.Length -le $_.Length) -and
($_.Extension -match $extRegex)
Expand Down Expand Up @@ -163,7 +163,7 @@ function Get-Hashes {
$hashList = @()

$Files = (
Get-ChildItem -Path $basePath -Recurse -Force -ErrorAction SilentlyContinue |
Get-ChildItem -Force -Path $basePath -Recurse -Force -ErrorAction SilentlyContinue |
? -FilterScript {
($_.Length -ge $MinB -and $_.Length -le $_.Length) -and
($_.Extension -match $extRegex)
Expand Down
4 changes: 2 additions & 2 deletions Modules/Disk/Get-FilesByHash.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ workflow Get-HashesWorkflow {
$hashList = @()

$Files = (
Get-ChildItem -Path $basePath -Recurse -ErrorAction SilentlyContinue |
Get-ChildItem -Force -Path $basePath -Recurse -ErrorAction SilentlyContinue |
? -FilterScript {
($_.Length -ge $MinB -and $_.Length -le $_.Length) -and
($_.Extension -match $extRegex)
Expand Down Expand Up @@ -170,7 +170,7 @@ function Get-Hashes {
$hashList = @()

$Files = (
Get-ChildItem -Path $basePath -Recurse -ErrorAction SilentlyContinue |
Get-ChildItem -Force -Path $basePath -Recurse -ErrorAction SilentlyContinue |
? -FilterScript {
($_.Length -ge $MinB -and $_.Length -le $_.Length) -and
($_.Extension -match $extRegex)
Expand Down
280 changes: 280 additions & 0 deletions Modules/Disk/Get-FilesByHashes.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
<#
.SYNOPSIS
Get-FilesByHash.ps1 scans the provided paths for files matching the provided hash.
.PARAMETER FileHash
Required. The file hash you are searching for. For example cmd.exe's hash (on
Windows 8.1) is 0B9BC863E2807B6886760480083E51BA8A66118659F4FF274E7B73944D2219F5
.PARAMETER HashType
Optional. Defaults to SHA-256.
.PARAMETER BasePaths
Optional. Limit your search to specific parent directories. When running stand-
alone, this can be an array. Kansa currenlty accepts only a sinlge path. Defaults
to all local disks.
.PARAMETER extRegex
Optional but highly recommended. Files must match the regex to be hashed.
.PARAMETER MinB
Optional. Minimum size of files to check in bytes. Defaults to 4096.
.PARAMETER MaxB
Optional. Maximum size of files to check in bytes. Defaults to 10485760.
.NOTES
OUTPUT TSV
When passing specific modules with parameters via Kansa.ps1's -ModulePath
parameter, be sure to quote the entire string, like shown here:
.\kansa.ps1 -ModulePath ".\Modules\Disk\Get-FilesByHash.ps1 9E2639ECE5631BAB3A41E3495C1DC119,MD5,C:\,\.ps1$"
As a note of warning, when reading files from %windir%\System32, if you are
running in a 32-bit PowerShell instance on a 64-bit system the Windows
filesystem API will transparently redirect your calls to %windir%\SysWOW64
instead, as documented in https://github.com/davehull/Kansa/issues/41. Using
the path %windir%\Sysnative will direct these calls to the 64-bit versions of
the applications (thanks @lanatmwan for the pointer to
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx).
#>

[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,Position=1)]
[String[]]$FileHashes,
[Parameter(Mandatory=$False,Position=2)]
[ValidateSet("MD5","SHA1","SHA256","SHA384","SHA512","RIPEMD160")]
[string]$HashType = "SHA256",
[Parameter(Mandatory=$False,Position=3)]
[String]$BasePaths,
[Parameter(Mandatory=$False,Position=4)]
[String]$extRegex="\.(exe|sys|dll|ps1)$",
[Parameter(Mandatory=$False,Position=5)]
[int]$MinB=4096,
[Parameter(Mandatory=$False,Position=6)]
[int]$MaxB=10485760
)

$ErrorActionPreference = "Continue"

function Get-LocalDrives
{
# DriveType 3 is localdisk as opposed to removeable. Details: http://msdn.microsoft.com/en-us/library/aa394173%28v=vs.85%29.aspx
foreach ($disk in (Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Select-Object -ExpandProperty DeviceID)) {
[string[]]$drives += "$disk\"
}

$driveCount = $drives.Count.ToString()
Write-Verbose "Found $driveCount local drives."
return $drives
}

workflow Get-HashesWorkflow {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$True,Position=0)]
[String]$BasePath,
[Parameter(Mandatory=$True,Position=1)]
[string[]]$SearchHashes,
[Parameter(Mandatory=$True,Position=2)]
[ValidateSet("MD5","SHA1","SHA256","SHA384","SHA512","RIPEMD160")]
[string]$HashType = "SHA256",
[Parameter(Mandatory=$False,Position=3)]
[int]$MinB=4096,
[Parameter(Mandatory=$False,Position=4)]
[int]$MaxB=10485760,
[Parameter(Mandatory=$False,Position=5)]
[string]$extRegex="\.(exe|sys|dll|ps1)$"
)

# Workflows are how PowerShell does multi-threading. The parent process
# spawns multiple child processes, which each receive the code contained
# within the parallel block. Once fed to a child, each command will run in
# non-deterministic order unless they are placed inside a sequence block.
#
# One problem we encountered when testing is that if the target host uses
# an SSD, this can max out that machine's CPU. I may expose the parameter
# to force single-threaded execution in the future.
#
# References:
# http://blogs.technet.com/b/heyscriptingguy/archive/2012/11/20/use-powershell-workflow-to-ping-computers-in-parallel.aspx
# http://blogs.technet.com/b/heyscriptingguy/archive/2012/12/26/powershell-workflows-the-basics.aspx
# http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/02/powershell-workflows-restrictions.aspx
# http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/09/powershell-workflows-nesting.aspx

$hashList = "" | Select-Object -Property File,Hash

$Files = (
Get-ChildItem -Force -Path $basePath -Recurse -ErrorAction SilentlyContinue |
? -FilterScript {
($_.Length -ge $MinB -and $_.Length -le $_.Length) -and
($_.Extension -match $extRegex)
} |
Select-Object -ExpandProperty FullName
)

foreach -parallel ($File in $Files) {

sequence {
$entry = inlinescript {
switch -CaseSensitive ($using:HashType) {
"MD5" { $hash = [System.Security.Cryptography.MD5]::Create() }
"SHA1" { $hash = [System.Security.Cryptography.SHA1]::Create() }
"SHA256" { $hash = [System.Security.Cryptography.SHA256]::Create() }
"SHA384" { $hash = [System.Security.Cryptography.SHA384]::Create() }
"SHA512" { $hash = [System.Security.Cryptography.SHA512]::Create() }
"RIPEMD160" { $hash = [System.Security.Cryptography.RIPEMD160]::Create() }
}

# -Message variable name required because workflows do not support possitional parameters.
Write-Debug -Message "Calculating hash of $using:File."
if (Test-Path -LiteralPath $using:File -PathType Leaf) {
$FileData = [System.IO.File]::ReadAllBytes($using:File)
$HashBytes = $hash.ComputeHash($FileData)
$paddedHex = ""

foreach( $byte in $HashBytes ) {
$byteInHex = [String]::Format("{0:X}", $byte)
$paddedHex += $byteInHex.PadLeft(2,"0")
}

Write-Debug -Message "Hash value was $paddedHex."
$hashes = $using:searchHashes
# if ($paddedHex -ieq $using:searchHashes) {
$index = $hashes.IndexOf($paddedHex)
if ($index -gt -1) {
$hashList.File = $using:File
$hashList.Hash = $hashes[$index]
$hashList
}
}
}
if ($entry) {
$workflow:hashList += $entry
}
}
}

return ,$hashList
}

function Get-Hashes {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$True,Position=0)]
[String]$BasePath,
[Parameter(Mandatory=$True,Position=1)]
[string[]]$SearchHash,
[Parameter(Mandatory=$True,Position=2)]
[ValidateSet("MD5","SHA1","SHA256","SHA384","SHA512","RIPEMD160")]
[string]$HashType = "SHA256",
[Parameter(Mandatory=$False,Position=3)]
[int]$MinB=4096,
[Parameter(Mandatory=$False,Position=4)]
[int]$MaxB=10485760,
[Parameter(Mandatory=$False,Position=5)]
[string]$extRegex="\.(exe|sys|dll|ps1)$"
)

# Single-threaded option since we ran into a few situations while testing
# where workflows aren't available.

$hashList = "" | Select-Object File,Hash

$Files = (
Get-ChildItem -Force -Path $basePath -Recurse -ErrorAction SilentlyContinue |
? -FilterScript {
($_.Length -ge $MinB -and $_.Length -le $_.Length) -and
($_.Extension -match $extRegex)
} |
Select-Object -ExpandProperty FullName
)

switch -CaseSensitive ($HashType) {
"MD5" { $hash = [System.Security.Cryptography.MD5]::Create() }
"SHA1" { $hash = [System.Security.Cryptography.SHA1]::Create() }
"SHA256" { $hash = [System.Security.Cryptography.SHA256]::Create() }
"SHA384" { $hash = [System.Security.Cryptography.SHA384]::Create() }
"SHA512" { $hash = [System.Security.Cryptography.SHA512]::Create() }
"RIPEMD160" { $hash = [System.Security.Cryptography.RIPEMD160]::Create() }
}

foreach ($File in $Files) {

Write-Debug -Message "Calculating hash of $File."
if (Test-Path -LiteralPath $File -PathType Leaf) {
$FileData = [System.IO.File]::ReadAllBytes($File)
$HashBytes = $hash.ComputeHash($FileData)
$paddedHex = ""

foreach( $byte in $HashBytes ) {
$byteInHex = [String]::Format("{0:X}", $byte)
$paddedHex += $byteInHex.PadLeft(2,"0")
}

Write-Debug -Message "Hash value was $paddedHex."
$index = $searchHashes.IndexOf($paddedHex)
if ($index -gt -1) {
$hashList.File = $Files
$hashList.Hash = $hashes[$index]
$objs += $hashList
}
}
}
$objs
}

function Get-Matches {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$True,Position=0)]
[String]$BasePath,
[Parameter(Mandatory=$True,Position=1)]
[string[]]$SearchHash,
[Parameter(Mandatory=$True,Position=2)]
[ValidateSet("MD5","SHA1","SHA256","SHA384","SHA512","RIPEMD160")]
[string]$HashType = "SHA256",
[Parameter(Mandatory=$False,Position=3)]
[int]$MinB=4096,
[Parameter(Mandatory=$False,Position=4)]
[int]$MaxB=10485760,
[Parameter(Mandatory=$False,Position=5)]
[string]$extRegex="\.(exe|sys|dll|ps1)$"
)

# Check if we're in a WOW64 situation. Thanks to MagicAndi on StackOverflow for this check.
# WOW64 doesn't support workflows (as far as I can tell) and has path redirection for the
# System32 directory (see module .SYNOPSIS).
if ((Test-Path env:\PROCESSOR_ARCHITEW6432) -and ([Intptr]::Size -eq 4)) {
$sysRegex = $env:SystemDrive.ToString() + "\\($|windows($|\\($|system32($|\\))))"
if ($BasePath -match $sysRegex) {
Write-Verbose "Searching %windir%\System32 with a 32-bit process on a 64-bit host can return false negatives. See comments in Get-FilesByHash.ps1 module for details."
}
}

$HashType = $HashType.ToUpper()

try {
$hashList = Get-HashesWorkflow -BasePath $BasePath -SearchHash $FileHashes -HashType $HashType -extRegex $extRegex -MinB $MinB -MaxB $MaxB
}
catch {
Write-Verbose -Message "Workflows not supported. Running in single-threaded mode."
$hashList = Get-Hashes -BasePath $BasePath -SearchHash $FileHashes -HashType $HashType -extRegex $extRegex -MinB $MinB -MaxB $MaxB
}

if ($hashList) {
Write-Verbose "Found files matching hash $FileHash (TK)."
foreach($entry in $hashList) {
$o = "" | Select-Object File, Hash
$o.File = $entry
$o.Hash = $FileHash # TK
$o
}
}
else {
Write-Verbose "Found no matching files."
}
}

if ($BasePaths.Length -eq 0) {
Write-Verbose "No path specified, enumerating local drives."
$BasePaths = Get-LocalDrives
}

foreach ($basePath in $BasePaths) {
Write-Verbose "Getting file hashes for $basePath."
Get-Matches -BasePath $BasePath -SearchHash $FileHashes -HashType $HashType -extRegex $extRegex -MinB $MinB -MaxB $MaxB
}
2 changes: 1 addition & 1 deletion Modules/Disk/Get-TempDirListing.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ OUTPUT tsv

foreach($userpath in (Get-WmiObject win32_userprofile | Select-Object -ExpandProperty localpath)) {
if (Test-Path(($userpath + "\AppData\Local\Temp\"))) {
Get-ChildItem ($userpath + "\AppData\Local\Temp\*") | Select-Object FullName, CreationTimeUtc, LastAccessTimeUtc, LastWriteTimeUtc
Get-ChildItem -Force ($userpath + "\AppData\Local\Temp\*") | Select-Object FullName, CreationTimeUtc, LastAccessTimeUtc, LastWriteTimeUtc
}
}
2 changes: 1 addition & 1 deletion Modules/Disk/Get-WebrootListing.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Param(
if (Test-Path $BasePath -PathType Container) {

$files = (
Get-ChildItem -Path $BasePath -Recurse -ErrorAction SilentlyContinue |
Get-ChildItem -Force -Path $BasePath -Recurse -ErrorAction SilentlyContinue |
? -FilterScript {
($_.Extension -match $extRegex) -and
($_.Length -ge $MinB -and $_.Length -le $MaxB)
Expand Down
19 changes: 19 additions & 0 deletions Modules/Log/Get-LogOpenSavePidlMRU.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function Get-RegKeyValueNData {
# Returns values and data for Registry keys
# http://blogs.technet.com/b/heyscriptingguy/archive/2012/05/11/use-powershell-to-enumerate-registry-property-values.aspx
Param(
[Parameter(Mandatory=$True,Position=0)]
[String]$Path
)
Push-Location
Set-Location -Path "Registry::$Path"
Get-Item -Force . | Select-Object -ExpandProperty Property |
Foreach-Object {
New-Object psobject -Property @{"property" = $_;
"value" = (Get-ItemProperty -Path . -Name $_).$_
}
}
Pop-Location
}

Get-RegKeyValueNData 'HKU\S-1-5-21-2127521184-1604012920-1887927527-8646616\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU\`*'
Loading

0 comments on commit 6def92e

Please sign in to comment.