Get-RemoteOpenFile.ps1

 
Function Get-RemoteOpenFile {
<#
.SYNOPSIS
Get a list of remote open file's on local or remote computers
 
.DESCRIPTION
This command uses Windows openfiles.exe to view files that are open by a user or process.
the command also requires administrative access on the remote/local computer the task is been executed.
 
 
.PARAMETER ComputerName
one or more computers names to query
 
.PARAMETER Filter
Filter to search for open files. wildcards supported *
 
.PARAMETER ErrorLogfilePath
if provided, this is a path and filename of a text file where failed computer names will be logged
 
.EXAMPLE
Get-RemoteOpenFiles -ComputerName Test-PC.test.local -filter D:\Files\*
 
.NOTES
if open file sessions needed to be closed use this commond in conjectection with Close-OpenFile whithin the pipeline
#>

[cmdletbinding()]

param(
[parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName,Mandatory=$True)]
[String[]]$ComputerName,
[parameter(ValueFromPipelineByPropertyName=$True)]
[String]$Filter,
[parameter(ValueFromPipelineByPropertyName=$True)]
[String]$ErrorLogfilePath
)


BEGIN {
    Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Starting: $($MyInvocation.MyCommand)"
    Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] PSVersion = $($PSVersionTable.PSVersion)"
    Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] OS = $((Get-CimInstance win32_OperatingSystem).Caption)"
    Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] User = $($env:userdomain)\$($env:USERNAME)"
    $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $IsAdmin = [System.Security.Principal.WindowsPrincipal]::new($id).IsInRole('administrators')
    Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Is Admin = $IsAdmin"
}

PROCESS {

    foreach($Computer in $ComputerName){
        Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] Testing connection to $($Computer)"
        if((Test-Connection -Computer $Computer -Quiet) -eq $True){
            Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] $($Computer) connection successful "
            try{
                Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] running openfiles.exe on $($Computer)"       
                $OpenFiles = openfiles /Query /S "$Computer"/FO CSV /V  | ConvertFrom-Csv | Where-Object "Open File (Path\executable)" -Like "$Filter" | `
                Select-Object  @{n="ComputerName";e={$_.Hostname}}, @{n="User";e={$_."Accessed By"}}, @{n="OpenMode";e={$_."Open Mode"}}, @{n="FileOpen";e={$_."Open File (Path\executable)"}}, @{n="ID";e={$_.ID}}
                $OpenFiles

            }#Try
            Catch {
                $($_.Exception.Message)    

            }#Catch
        }#IF
        else{
            Write-Error "Cannot connect to computer $($Computer). please check connection and computer name"
            if($ErrorLogfilePath){
                Write-Verbose "ErrorLog file created in path $($ErrorLogfilePath)"
                Write-Output $Computer | Out-File $ErrorLogfilePath -Append 

            }#IF
        }
    }#ForEach


}

END {
    #leftBlank
}
}#Function