Reputation: 175
I am working on building a PowerShell script that will find all the jpeg/jpg files on a machine. This is what I have so far-
# PowerShell script to list the DLL files under the C drive
$Dir = get-childitem C:\ -recurse
# $Dir |get-member
$List = $Dir | where {$_.extension -eq ".jpg"}
$List |ft fullname |out-file C:\Users\User1\Desktop\dll.txt
# List | format-table name
The only problem is that some of the files I am looking for don't have the extension jpg/jpeg. I know that you can look in the header of the file and if it says ÿØÿà then it is a jpeg/jpg but I don't know how to incorporate this into the script.
Any help would be appreciated. Thanks so much!
Upvotes: 1
Views: 9271
Reputation: 1202
How about this one?
jp*g
is used to match both jpg and jepg images.
$List = Get-ChildItem "C:\*.jp*g" -Recurse
$List |ft fullname |out-file C:\Users\User1\Desktop\dll.txt
Upvotes: 0
Reputation: 1740
I would recommend querying the windows search index for the jpegs, rather than trying to sniff file contents. Searching the system index using filenames is insanely fast, the downside is that you must search indexed locations.
I wrote a windows search querying script using the windows sdk \samples\windowssearch\oledb, you would want to query using the imaging properties. However, I'm not certain off the top of my head if the search index uses the imaging api to look at unknown files or files without extensions. Explorer seems to know my jpeg thumbnails and metadata without jpg extensions, so I'm guessing the indexer is going to be as clever as explorer.
Upvotes: 1
Reputation: 16612
The following will retrieve files with either a .jpg
/.jpeg
extension or that contain a JPEG header in the first four bytes:
[Byte[]] $jpegHeader = 255, 216, 255, 224;
function IsJpegFile([System.IO.FileSystemInfo] $file)
{
# Exclude directories
if ($file -isnot [System.IO.FileInfo])
{
return $false;
}
# Include files with either a .jpg or .jpeg extension, case insensitive
if ($file.Extension -match '^\.jpe?g$')
{
return $true;
}
# Read up to the first $jpegHeader.Length bytes from $file
[Byte[]] $fileHeader = @(
Get-Content -Path $file.FullName -Encoding Byte -ReadCount 0 -TotalCount $jpegHeader.Length
);
if ($fileHeader.Length -ne $jpegHeader.Length)
{
# The length of the file is less than the JPEG header length
return $false;
}
# Compare each byte in the file header to the JPEG header
for ($i = 0; $i -lt $fileHeader.Length; $i++)
{
if ($fileHeader[$i] -ne $jpegHeader[$i])
{
return $false;
}
}
return $true;
}
[System.IO.FileInfo[]] $jpegFiles = @(
Get-ChildItem -Path 'C:\' -Recurse `
| Where-Object { IsJpegFile $_; }
);
$jpegFiles | Format-Table 'FullName' | Out-File 'C:\Users\User1\Desktop\dll.txt';
Note that the -Encoding
and -TotalCount
parameters of the Get-Content
cmdlet are used to read only the first four bytes of each file, not the entire file. This is an important optimization as it avoids basically reading every byte of file data on your C:
drive.
Upvotes: 3
Reputation: 200453
This should give you all files starting with the sequence "ÿØÿà":
$ref = [byte[]]@(255, 216, 255, 224)
Get-ChildItem C:\ -Recurse | ? { -not $_.PSIsContainer } | % {
$header = [System.IO.File]::ReadAllBytes($_.FullName)[0..3]
if ( (compare $ref $header) -eq $null ) {
$_.FullName
}
} | Out-File "C:\Users\User1\Desktop\dll.txt"
Upvotes: 2
Reputation: 2947
To find if the header starts with ÿØÿà, use:
[System.String]$imgInfo = get-content $_ # where $_ is a .jpg file such as "pic.jpg"
if($imgInfo.StartsWith("ÿØÿà"))
{
#It's a jpeg, start processing...
}
Hope this helps
Upvotes: 1
Reputation: 1550
I'm not sure how to use powershell native commands to Look at file headers, I will do some research on it because it sounds fun. Until then I can suggest a shorter version of your initial command, reducing it to a one liner.
Get-ChildItem -Recurse -include *.jpg | Format-table -Property Fullname | Out-file C:\Users\User1\Desktop\Jpg.txt
or
ls -r -inc *.jpg | ft Fullname
EDITED: removed redundant code, thanks @nick.
I'll let you know what I find if I find anything at all.
Chris
Upvotes: 3