Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell: What is the best way to check whether the current user has permission to overwrite a file in PowerShell?

TL;DR

At the beginning of my script, I would like to check whether a file (given as a parameter) is overwritable, and quit if the current user does not have permission to do that.
(For example, if the user or the group he/she belongs to has been denied access for a file.)

The reason: in the script, I'm processing some data (which takes time), and at the end, I write the results into a file, but it would be a bit frustrating that the whole script ran correctly, but at the end, it turns out that the file is not writable (which I could have checked at the beginning).


What I tried

This is a correct way to test whether a file exists:

$Outfile = "w:\Temp\non-writable-file.txt"                # (normally I get this as a parameter)
$OutFileExists = Test-Path -Path $Outfile -PathType Leaf

Of course, $OutfileExists will be equal to True if the file exists.

But I would like to check whether this file is writable - now it's not (I changed the security settings myself to be able to test it):

Everyone - denied from writing

So, if I try this:

(Get-Acl $Outfile).Access

I get this output:

FileSystemRights  : Write
AccessControlType : Deny
IdentityReference : Everyone
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

FileSystemRights  : ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : Everyone
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : DOESNTMATTER\Pete
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

(I could also have filtered this result.)
OK, now I know that the Everyone group has no write access.
But I still don't know how to check the overwritability of this file elegantly.

like image 365
Sk8erPeter Avatar asked Apr 08 '14 16:04

Sk8erPeter


2 Answers

I've used this:

Try { [io.file]::OpenWrite($outfile).close() }
 Catch { Write-Warning "Unable to write to output file $outputfile" }

It will attempt to open the file for write access, then immediately close it (without actually writing anything to the file). If it can't open the file for any reason, it will run the Catch block, and you can do your error handling there.

like image 137
mjolinor Avatar answered Oct 05 '22 09:10

mjolinor


You could attempt a quick write (append) to the file such as

"" | Out-File 'w:\Temp\non-writable-file.txt' -Append

Where no write permissions exist you will receive an error:

Out-File : Access to the path 'w:\Temp\non-writable-file.txt' is denied.
...
+ CategoryInfo : OpenError: (:) [Out-File], UnauthorizedAccessException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

You could catch and terminate on that error, in the case where write permission exists - you've just appended a new line to the file.

like image 22
bob Avatar answered Oct 05 '22 09:10

bob