Dear Stackoverflow Community!
I've got a question concerning Windows Defender, Attack Surface Reduction and Endpoint Device Manager.
To prevent LNK Worm Expoitation I want to block .LNK files on removable devices (USB drives). Example: User inserts USB Drive and doubleclicks on a file 'USB Drive.lnk' which, in fact, is malicious.
Unfortunately after a lot of research and testing I have yet not found a satisfying solution for my problem. Maybe some of you had a similar problem.
Many thanks in advance!
Best regards
Solved it myself.
I enabled logging in event viewer under the path "Application and Services Logs\Microsoft\Windows\DriverFrameworks-UserMode".
Then created an Task in Task Scheduler that gets activated when Event ID 2003 is found in above path.
This task then executes a scripts that searches for .lnk files on USB sticks that have the drive letter D:.
#
# ------------- Globals -------------
#
# drive letter of usb device
$USBDeviceDriveLocation = "D:\"
# .lnk extensio
$LNKExtentsion = ".lnk"
#
# ------------- Functions -------------
#
function SearchAndRemoveFilesWithExtension
{
<#
#>
# file extension as parameter
param
(
$extension
)
# iterate through files and delete them
$FoundFiles = Get-ChildItem -Recurse -Path D:\ -Include "*$extension"
# if none lnk files found then exit
if ($FoundFiles.Count -eq 0)
{
exit
}
# remove those files
foreach ($file in $FoundFiles)
{
Remove-Item -Path $file.FullName
}
}
function Main
{
<#
.SYNOPSIS
Main Method
#>
SearchAndRemoveFilesWithExtension $LNKExtentsion
}
#
#
#
Main
Related
So I'm trying to count the number of font files (that have different extensions) inside the local font folder of every computer in my domain at work to verify which computers have an up to date font installation using powershell.
So far I have
Write-Host ( Get-ChildItem c:\MyFolder | Measure-Object ).Count;
as a means of counting the files, I'm just at a loss on how exactly to replicate this and get a output that indicates the file count for the path for every computer on my domain (the file path is all the same for each)
How should I best proceed?
You will have to run the command against every computer. Assuming you have some sort of domain admin privelege and can access admin shares on all computers, you can use the c$ share.
The code below takes a list of computers in a single column CSV with no headers and runs the command against the admin share on each
$computers = Import-Csv -Path C:\computers.csv -Header Computer;
foreach($c in $computers)
{
Write-Host (Get-ChildItem "\\$($c.Computer)\c$\MyFolder" | Measure-Object).Count;
};
I want to be able to list the currently installed windows xbox store apps, and at least what hard drive they are installed to, though the installed size would also be helpful.
As an example, I've installed Astroneer to my D:\ drive. I can see the installation location:
# Astroneer folder
D:\WindowsApps\SystemEraSoftworks.29415440E1269_1.21.128.0_x64__ftk5pbg2rayv2\
# Other game package types can install to an MSIXVC file, e.g.
D:\WindowsApps\MSIXVC\130F32F8-4ABB-49E2-9200-3C4FCE2271C8
I can see the appx package, but its InstallLocation points to a junction point within the default appx volume instead:
Get-AppxPackage -Name "SystemEraSoftworks*"
Name : SystemEraSoftworks.29415440E1269
Publisher : CN=115C80E5-07B4-4D9C-8912-5562D4A1828D
Architecture : X64
ResourceId :
Version : 1.21.128.0
PackageFullName : SystemEraSoftworks.29415440E1269_1.21.128.0_x64__ftk5pbg2rayv2
InstallLocation : C:\Program Files\WindowsApps\SystemEraSoftworks.29415440E1269_1.21.128.0_x64__ftk5pbg2rayv2
The appx manifest doesn't contain any information about which drive the app is installed on.
I searched through the registry a bit, but only found references to the C:\ path, or using relative paths like:
Get-ItemProperty 'hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModel\StateRepository\Cache\Activation\Data\18a' -Name 'Executable'
Executable : Astro\Binaries\UWP64\Astro-UWP64-Shipping.exe
I found I could parse the junction points with Get-Item and check the install folders for xbox config files:
# List all windows store packages. May want to include -AllUsers?
Get-AppxPackage |
# Filter out unwanted packages
Where {!$_.IsFramework -and !$_.NonRemovable -and $_.SignatureKind -eq 'Store'} |
Select Name, #{l='InstallLocation';e={
# Return the junction target instead of the local install folder
If ((Get-Item $_.InstallLocation).LinkType -eq 'Junction') {
(Get-Item $_.InstallLocation).Target
}
Else { $_.InstallLocation }
}} |
# Filter to Xbox games
Where { Test-Path "$($_.InstallLocation)\MicrosoftGame.config" }
# Outputs:
Name InstallLocation
---- ---------------
KalypsoMediaGroup.Tropico6Win C:\Program Files\WindowsApps\KalypsoMediaGroup.Tropico6Win_15.3.553.0_x64__e60j8nnj33ga6
WarnerBros.Interactive.e172091a-6630-4ff3-959f-830 F:\WindowsApps\WarnerBros.Interactive.e172091a-6630-4ff3-959f-830_1.279.9438.0_x64__ktmk1xygcecda
SystemEraSoftworks.29415440E1269 D:\WindowsApps\SystemEraSoftworks.29415440E1269_1.21.128.0_x64__ftk5pbg2rayv2
I'm not sure if I can find the package installation sizes anywhere though, although they are listed in the xbox app.
I have to re-mount removable drives (which require authentication) each time I boot the computer and Windows Indexing keeps removing the removable drives (perhaps because the removable drives are not available when the computer boots). In an ideal world Windows Indexing would keep these locations and just list them as 'Unavailable' (which it sometimes does). However because it doesn't I am interested in executing a script that queries the Windows Indexing locations and if it does not list the removable drives then add them. At the bottom of this thread I pasted the Batch script that I setup to run at boot (via Start Up folder) to search for a specific folder that is available thereafter mounting one of the removable drives.
I have found several examples of how to do this on Windows 7 (links pasted below) but I can't figure out how to do it in Windows 10. The links provided to the DLL (Microsoft.Search.Interop.dll) no longer resolve.
When searching for the latest Windows Search SDK for Windows 10 I was lead to the Windows SDK here:
https://learn.microsoft.com/en-us/windows/win32/search/-search-developers-guide-entry-page
I installed the C++ related portion of the Windows SDK then searched for Microsoft.Search.Interop.dll but I couldn't find it. Perhaps the DLL has changed?
From How to rebuild Windows Search Index by using PowerShell?
Load DLL containing classes & interfaces
Add-Type -path "C:\Temp\SearchIndexSdk\Microsoft.Search.Interop.dll"
#Provides methods for controlling the Search service. This
interface manages settings and objects that affect the search engine
across catalogs.
https://msdn.microsoft.com/en-us/library/bb231485(v=vs.85).aspx
$sm = New-Object Microsoft.Search.Interop.CSearchManagerClass
#Retrieves a catalog by name and creates a new ISearchCatalogManager
object for that catalog.
$catalog = $sm.GetCatalog("SystemIndex")
#Resets the underlying catalog by rebuilding the databases and performing a full indexing.
#https://msdn.microsoft.com/en-us/library/bb266414(v=vs.85).aspx
$catalog.Reset()
From How to add a location to windows 7/8 search index using batch or vbscript?
#Code copied from "Powershell Tackles Windows Desktop Search" http://powertoe.wordpress.com/2010/05/17/powershell-tackles-windows-desktop-search/
#Microsoft.Search.Interop.dll is needed, download from http://www.microsoft.com/en-us/download/details.aspx?id=7388
#Load the dll
Add-Type -path "D:\Unattend\UserFiles\Tools\Microsoft.Search.Interop.dll"
#Create an instance of CSearchManagerClass
$sm = New-Object Microsoft.Search.Interop.CSearchManagerClass
#Next we connect to the SystemIndex catalog
$catalog = $sm.GetCatalog("SystemIndex")
#Get the interface to the scope rule manager
$crawlman = $catalog.GetCrawlScopeManager()
#add scope
$crawlman.AddUserScopeRule("file:///D:*",$true,$false,$null)
$crawlman.SaveAll()
I would add a comment to the existing threads but I am not able to because I don't have reputation of 50 (dumb rule IMO).
Last... I found this site which lists the DLL along with some code but it hasn't been updated in a long time.
https://github.com/FileMeta/WindowsSearchSample
Thanks in advance!
Batch script that runs at boot:
#echo off
echo Windows Search is being restarted to recognize the Z drive
:while
if EXIST Z:\Watch (
I WANT TO CALL POWERSHELL SCRIPT TO ADD THE LOCATION TO THE INDEX IF NEEDED HERE
sc stop WMPNetworkSvc
ping 127.0.0.1 -n 5 > nul
sc stop WSearch
ping 127.0.0.1 -n 5 > nul
sc start WSearch
ping 127.0.0.1 -n 5 > nul
sc start WMPNetworkSvc
echo Exiting this script in 5 seconds
ping 127.0.0.1 -n 5 > nul
exit
) else (
echo Waiting 60 seconds to check if Z drive is available
ping 127.0.0.1 -n 60 > nul
goto :while
)
When I do a search for Searchdll in what I believe to be the folder where the Windows SDK installed to (C:\Program Files (x86)\Windows Kits\10) I find the following. If I had to guess which DLL is the Windows 10 equivalent of Windows 7's Microsoft.Search.Interop.dll I would guess that it's the 1st one i.e. interop.searchapi.dll.
Add-Type -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\interop.searchapi.dll" does return without error... however $sm = New-Object Microsoft.Search.Interop.CSearchManagerClass returns with error that it cannot find the class in the assembly.
When I cd to "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64" and enter ([appdomain]::currentdomain.GetAssemblies() | Where-Object Location -Match 'interop.searchapi').gettypes() I get the following
When I enter (([appdomain]::currentdomain.GetAssemblies() | Where-Object location -match 'interop.searchapi.dll').gettypes() | Where-Object name -eq 'CSearchManagerClass').getmembers() | Format-Table name, membertype I get
From the list of commands in the previous threads I do see GetCatalog and I presume that the members GetCrawlScopeManager, AddUserScopeRule, Reset, and SaveAll exist.
I don't know how to find the fully qualified class name or I'm doing something else wrong (unknowingly).
When I enter ([appdomain]::currentdomain.GetAssemblies() | Where-Object Location -Match 'interop.searchapi').fullname I get the following
Interop.SearchAPI, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
But when I enter $sm = New-Object Interop.SearchAPI.CSearchManagerClass I get an error that it can't find the type Interop.SearchAPI.CSearchManagerClass.
Same question exists for Python here: How can I get the Dropbox folder location programmatically in Python?, or here for OSX: How to get the location of currently logined Dropbox folder
Same thing in Powershell. I need the path of DropBox to copy files to it (building a software and then copying it to dropbox to share with team).
This Dropbox help page tells us where this info is stored, ie, in a json file in the AppData of the user: https://www.dropbox.com/help/4584
function GetDropBoxPathFromInfoJson
{
$DropboxPath = Get-Content "$ENV:LOCALAPPDATA\Dropbox\info.json" -ErrorAction Stop | ConvertFrom-Json | % 'personal' | % 'path'
return $DropboxPath
}
The line above is taken from: https://www.powershellgallery.com/packages/Spizzi.Profile/1.0.0/Content/Functions%5CProfile%5CInstall-ProfileEnvironment.ps1
Note that it doesn't check if you've got a Dropbox business account, or if you have both. It just uses the personal one.
You can then use this base Dropbox folder to build your final path, for example:
$targetPath = Join-Path -Path (GetDropBoxPathFromInfoJson) -ChildPath 'RootDropboxFolder\Subfolder1\Subfolder2'
if (-not (Test-Path -Path $targetPath)) { throw "Path '$targetPath' not found!" }
--
Alternative way is using the host.db file, as shown on this page:
http://bradinscoe.tumblr.com/post/75819881755/get-dropbox-path-in-powershell
$base64path = gc $env:appdata\Dropbox\host.db | select -index 1 # -index 1 is the 2nd line in the file
$dropboxPath = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($base64path)) # convert from base64 to ascii
Help please. I can not find a solution. (Windows platform)
I need to:
Scan the folder
If you receive any new file.
Process the file.
Another method to detect "new files" is the archive attribute. Whenever a file is created or changed, this attribute is set by windows.
Whenever you process a file, unset it's archive attribute (attrib -a file.ext).
The advantage is, you don't depend on any timing.
To list "new" (or changed) files, use dir /aa (dir /a-a will list processed files)
for more infos see dir /? and attrib /?
Without knowing exactly what you're trying to execute, this is all I can provide. You would theoretically run this as a scheduled task every 1 hour:
foreach ($file in (Get-ChildItem "C:\TargetDirectory" | where {$_.lastwritetime -gt (Get-Date).AddHours(-1)})) {
# Execute-Command -Target $file
}
You could use the FileSystemWatcher class to monitor the folder for new files.
It can easily be used from PowerShell as well:
$FSW = New-Object System.IO.FileSystemWatcher
Then use Register-ObjectEvent to "listen" for events raised from it
FileSystemWatcher is a utility I have recently learned and will definitely use in the future. The best part is that it relies on .net eventing, so you don't need to build an external triggering structure.
Here is an example of how I am using this in a 24/7 production environment (the full script receives an xml, processes it, and inserts the results into SQL in under 3 seconds).
Function submit-resultFile {
#Actual file processing takes place here
}
Function create-fsw {
Register-ObjectEvent $fsw Created -SourceIdentifier "Spectro FileCreated" -Action {
$name = $Event.SourceEventArgs.Name
$File = $Event.SourceEventArgs.Fullpath
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Verbose "The file '$name' was $changeType at $timeStamp" -fore green
submit-ResultFile -xmlfile $file
}
}
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$fsw = New-Object IO.FileSystemWatcher $watchFolder, $watchFilter -Property #{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
$xmlFiles = Get-ChildItem -Path $ResultsDirectory -Filter *.xml
foreach ($file in $xmlfiles)
{
submit-ResultFile -xmlfile $File.FullName
}
Create-fsw
# Register a new File System Watcher
Several important points to be aware of:
- if files exist in that location before the FSW is created they WILL NOT trigger an "objectevent", so in my script you'll observe that I begin by running a sweep for existing files.
when FSW does trigger you want it to process only 1 file at a time. Since the next file creation event will generate a new "objectevent". Structuring a FSW to work on multiple files per trigger will eventually result in a crash.