Close-OpenFile.ps1
Function Close-OpenFile { <# .SYNOPSIS Closes open files on local or remote computers .DESCRIPTION This command uses Windows openfiles.exe to close files that are open by a user or process. the command requires administrative access on the remote/local computer where task is been executed. .PARAMETER ComputerName one or more computers names to query .PARAMETER ID File ID can be retrived by running Get-RemoteOpenFile .PARAMETER User User with file open .PARAMETER ErrorLogfilePath if provided, this is a path and filename of the text file where failed computer names will be logged .EXAMPLE Import-csv FileList.csv | Close-OpenFile -ErrorLogfilePath C:\Logs\Logs.txt .EXAMPLE Get-RemoteOpenFile -ComputerName Test-PC.test.local -filter D:\Files\* | Close-OpenFile -ErrorLogfilePath C:\Logs\Logs.txt .NOTES Input from pipeline is supported for ComputerName & FileID. This command works together with Get-RemoteOpenFile command run first to get required file's to close. #> [cmdletbinding(SupportsShouldProcess=$True,ConfirmImpact='high')] param ( [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Mandatory=$True)] [string[]]$ComputerName, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$True)] [String]$ID, [parameter(ValueFromPipelineByPropertyName=$True,Mandatory=$False)] [String]$User, [parameter(ValueFromPipelineByPropertyName=$False,Mandatory=$False)] $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)" $UserId = [System.Security.Principal.WindowsIdentity]::GetCurrent() $IsAdmin = [System.Security.Principal.WindowsPrincipal]::new($UserId).IsInRole('administrators') Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Is Admin = $IsAdmin" } PROCESS { try { If ($PSCmdlet.ShouldProcess($ComputerName)){ ForEach($Computer in $ComputerName){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] trying to close files" $ClosedFile = openfiles /s "$Computer" /disconnect /id $ID $Props = [Ordered]@{ "User" = $User; "Computer" = $Computer "Status" = $ClosedFile } $FileStauts = New-Object -TypeName psobject -Property $Props $FileStauts }#ForEach }#IF }#Try Catch { $($_.Exception.Message) if($ErrorLogfilePath){ Write-Verbose "ErrorLog file created in path $($ErrorLogfilePath)" Write-Output "[$((get-date).TimeOfDay.ToString()) ERROR ] closing file $($ClosedFile) in $($Computer) accessed by user $($User)" | Out-File $ErrorLogfilePath -Append }#IF }#Catch }#Process END{ #LeftBlank } }#Function |