How to grant access to create a new file? - powershell

With a PowerShell script I try to create a new file as follows:
New-Item -Path $LogDir -Value $LogName -Force -ItemType File
which is refused with the following error messsage:
New-Item : Access to the path 'D:\Testing\Data\Powershell\Log' is denied.
At D:\Testing\Data\Powershell\LoadRunner\LRmain.ps1:27 char:9
+ New-Item <<<< -Path $LogDir -Value $LogName -Force -ItemType File
+ CategoryInfo : PermissionDenied: (D:\Testing\Data\Powershell\Log:String) [New-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : NewItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand
I am executing the script in an Administrator PowerShell 2.0 window on Windows Server 2008. The directory exists, but how can I fix this error?

I'll add #PetSerAl's answer so we can close this question.
You've used the wrong parameter for the filename. Replace -Value with -Name, ex:
New-Item -Path $LogDir -Name $LogName -Force -ItemType File

Related

Why does powershell throw a path does not exist error?

Why does powershell throw an error when trying to create or modify a registry key from the docs I used
Set-ItemProperty -Path "HKLM:\Software\ContosoCompany" -Name "NoOfEmployees" -Value 823
The error I get
Set-ItemProperty : Cannot find path 'HKLM:\Software\ContosoCompany' because it does not exist.
At line:1 char:1
+ Set-ItemProperty -Path "HKLM:\Software\ContosoCompany" -Name "NoOfEmp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (HKLM:\Software\ContosoCompany:String) [Set-ItemProperty], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetItemPropertyCommand
I am running the powershell as an admin and I tried to modify existing keys and also tried to create new ones but I still get this error
HKLM is the name of a 'drive'. Move there first
Set-Location HKLM:
Set-ItemProperty -Path "HKLM:\Software\ContosoCompany" -Name "NoOfEmployees" -Value 823

Copy Files on Same Directory using Powershell

I am trying to write powershell Script which will create backupfolder on same Path where Application exist and need to copy the folders & files into backupfolder before deploying. Below are the command was using to perform but am getting error
$Source = "C:\XYZ"
$BackupFolder = New-Item -ItemType Directory -Force -Path $source_$(Get-Date)
Copy-Item -Path $Source\* $BackupFolder -Force
Error: Cannot copy item C:\XYZ\Backup_18-02-2017 on to itself
Try:
Copy-Item $Source\* $BackupFolder -Exclude $BackupFolder
That will eliminate the folder that you are copying into as a source that is being copied from.
Variables can contain underscores. The following works and displays the string "asdf"
$a_ = "adsf"; $a_
Your New-Item cmdlet call should have failed since $source_ is not a variable and would return null. This is default behavior for PowerShell. When I run your code as is I get the following:
New-Item : Cannot find drive. A drive with the name '02/18/2017 22' does not exist.At line:1 char:1
+ New-Item -ItemType Directory -Force -Path "$source_$(Get-Date)" -what ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (02/18/2017 22:String) [New-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.NewItemCommand
So I would have expected your folder variable to be null. wOxxOm brings this up in comment as well
Several options to address what I am sure is the partial source of your issue.
$BackupFolder = New-Item -ItemType Directory -Force -Path "$source`_$(Get-Date)"
$BackupFolder = New-Item -ItemType Directory -Force -Path "$($source)_$(Get-Date)"
$BackupFolder = New-Item -ItemType Directory -Force -Path ("{0}_{1} -f "$source, Get-Date)
You will still have to try and exclude this folder from the copy as well like Keith Hill's answer is telling you
Copy-Item $Source\* $BackupFolder -Exclude $BackupFolder
try Something like this
$Source = "C:\XYZ"
$Destination="{0}{1:yyyyMMdd}" -f $source, (Get-Date)
New-Item -ItemType Directory -Force -Path $Destination
Copy-Item -Path $Source\* $Destination -Recurse -Force
If I understand the question correctly. You want to take "C:\XYZ" and backup into the same directory called "C:\XYZ\backup_$DATE". What you will actually do is create a loop that will break once it reaches the max 248 characters. If we use the -exclude option then we can exclude the backup directory "C:\XYZ\backup_$DATE".
This function will do the trick and also gives you error handling.
Function Get-CopyDirectory{
#####################
# Dynamic Variables #
#####################
$Date = Get-Date -format ddMM-yyyy
$Exclude="Backup*"
####################
# Static Variables #
####################
$AppPath = "F:\Test\"
$BackupPath = "$AppPath\BACKUP_$Date\"
if (Test-Path $BackupPath) {
Write-Host "Backup Exist" -f Cyan
}
else
{
Copy-Item "$AppPath\*" $BackupPath -Exclude $Exclude -recurse -verbose
}
}
CLS
Get-CopyDirectory

Error message in script

I am trying to script a solution copying some files from one location to another..
I have a list of files in a .csv format, with headers
"ParentFolder, Name, FullName, lastwritetime."
Content of file is, which has hundreds of lines, and different paths, but same drive letter:
"X:\clients\A90\201AA3.05\","2012.08 RAP Proposal.xlsm","X:\clients\A90\201AA3.05\2012.08 RAP Proposal.xlsm","20/05/2016 10:41:08"
What i would like to do is copy the above..
"X:\clients\A90\201AA3.05\2012.08 RAP Proposal.xlsm" to a new location with differnet drive, but same directory structure. So in the csv file i have the filename and path, but am unsure how to split the drive from there and make a variable.
I have a foreach loop..
$ToCopy = Import-Csv "c:\temp\log.csv"
foreach($Line in $ToCopy)
{
$FullPath = $Line.ParentFolder
$File = $Line.Name
$FullName = $Line.FullName
$file = "$FullPath\$FullName"
$DestPath = Split-Path $FullPath -NoQualifier
Copy-Item "$FullName" -Destination c:\test\$DestPath
}
Error message that i am getting is :
+ CategoryInfo : NotSpecified: (:) [Copy-Item], DirectoryNotFoundException
+ FullyQualifiedErrorId : System.IO.DirectoryNotFoundException,Microsoft.PowerShell.Commands.CopyItemCommand
Copy-Item : Could not find a part of the path 'C:\test\clients\A90\Support\_index0901\'.
At line:9 char:9
+ Copy-Item "$FullName" -Destination c:\test\$DestPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], DirectoryNotFoundException
+ FullyQualifiedErrorId : System.IO.DirectoryNotFoundException,Microsoft.PowerShell.Commands.CopyItemCommand
You get the error because the directory structure of your target path probably does not exist
To solve that you can create a 'temporary' file with New-Item ... -Force which creates the missing directories if necessary and then overwrite that file with Copy-Item like so
$ToCopy = Import-Csv "c:\temp\log.csv"
foreach($Line in $ToCopy)
{
$FullPath = $Line.ParentFolder
$File = $Line.Name
$FullName = $Line.FullName
$file = "$FullPath\$FullName"
$DestPath = Split-Path $FullPath -NoQualifier
$DestFile = c:\test\$DestPath
New-Item -ItemType File -Force $DestFile
Copy-Item "$FullName" -Destination $DestFile -Force
}
You need to create the folders before attempting to copy files in them.
Here's a way to do it, simplified from what you have, but with an added line to take care of the folders' creation.
foreach($File in $ToCopy)
{
$DestPath = Join-Path -Path 'c:\test' -ChildPath ( Split-Path $File.ParentFolder -NoQualifier )
If ( -not ( Test-Path -Path $DestPath ) ) { New-Item -Path $DestPath -Force -ItemType Directory }
Copy-Item $File.FullName -Destination $DestPath -WhatIf
}
(Be careful, I change the iteration variable from $Line to $File)
You are trying to copy files into c:\test\ directory which does not exist. Create this directory before loop:
mkdir c:\test\
or, in case directory may exist
mkdir c:\test\ -Force

PowerShell script takes days to finish

The following script runs great except for the fact that it takes days to finish. Does anyone have any tweaks or tips to cut down the execution time?
The shared directory, Images\Equipment, contains over 5500 folders is grows daily.
# If the Admin folder for Equipment Images does not exist, make a new one and set the correct permissions.
$Location = "E:\Images\Equipment\*\"
$file = "E:\Images\Equipment\*\Admin"
foreach ($_ in (Get-ChildItem E:\Images\Equipment\*\)){if(($_.PSIsContainer -AND $_.name -eq "Admin")-eq $false)
{
New-Item -Path $location -Name "Admin" -ItemType directory
$errorActionPreference = "continue"}}
$folder = "E:\Images\Equipment\*\Admin"
Get-ChildItem E:\Images\Equipment\ -Directory -Filter "admin" -Recurse | ForEach-Object {
$acl = Get-Acl $_.FullName
if ($acl.AreAccessRulesProtected) { $acl.Access | % {$acl.purgeaccessrules($_.IdentityReference)} }
else {
$isProtected = $true
$preserveInheritance = $false
$acl.SetAccessRuleProtection($isProtected, $preserveInheritance)
}
$account="recoequip\folder sales group"
$rights=[System.Security.AccessControl.FileSystemRights]::FullControl
$inheritance=[System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation=[System.Security.AccessControl.PropagationFlags]::None
$allowdeny=[System.Security.AccessControl.AccessControlType]::Allow
$dirACE=New-Object System.Security.AccessControl.FileSystemAccessRule ($account,$rights,$inheritance,$propagation,$allowdeny)
$ACL.AddAccessRule($dirACE)
Set-Acl -aclobject $ACL -Path $folder
Write-Host $folder Permissions added}
Thank you for any assistance.
Sara
Ok, to try and speed up your script I would create the ACE once at the beginning as suggested by mjolinor in his comment above. I would not bother looking for folders that are missing an Admin subfolder, and just create the Admin sub-folder in each folder regardless, and use the -force argument. That won't delete and re-create, but what it will do is return a folder object for each folder even if it already existed. Collect all those folders in a variable. Then iterate through those folders and apply the correct permissions for them.
# If the Admin folder for Equipment Images does not exist, make a new one and set the correct permissions.
#Define ACE to apply
$account="recoequip\folder sales group"
$rights=[System.Security.AccessControl.FileSystemRights]::FullControl
$inheritance=[System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation=[System.Security.AccessControl.PropagationFlags]::None
$allowdeny=[System.Security.AccessControl.AccessControlType]::Allow
$dirACE=New-Object System.Security.AccessControl.FileSystemAccessRule ($account,$rights,$inheritance,$propagation,$allowdeny)
#Make sure all Equipment Images folders have an 'Admin' subfolder, and store the folder objects for later
$Folders = Get-ChildItem E:\Images\Equipment\* -Directory | %{New-Item -Path ($_.FullName + "\Admin") -ItemType directory -ErrorAction Continue -Force}
ForEach($Folder in $Folders){
$acl = Get-Acl $Folder.FullName
if ($acl.AreAccessRulesProtected) { $acl.Access | % {$acl.purgeaccessrules($_.IdentityReference)} }
else {
$isProtected = $true
$preserveInheritance = $false
$acl.SetAccessRuleProtection($isProtected, $preserveInheritance)
}
$ACL.AddAccessRule($dirACE)
Set-Acl -aclobject $ACL -Path $folder
Write-Host $folder Permissions added
}
This does assume that you are using PSv3 or better and have access to the -Directory switch for the Get-ChildItem cmdlet. If you do not have v3 installed I would suggest upgrading your version of PowerShell. I realize that's not always an option so alternatively you can change line 12 to this:
$Folders = Get-ChildItem E:\Images\Equipment\* -Attributes Directory | %{New-Item -Path ($_.FullName + "\Admin") -ItemType directory -ErrorAction Continue -Force}
or
$Folders = Get-ChildItem E:\Images\Equipment\* | ?{$_.PSIsContainer} | %{New-Item -Path ($_.FullName + "\Admin") -ItemType directory -ErrorAction Continue -Force}
If you have to use one of these I would suggest the first one since that filters for only directories at the FileSystem Provider level, instead of returning all folders and files, and then making PowerShell filter out the files.
This was to long to add in a comment.
This is the error it gives repeatedly in between assigning permissions to certain Admin folders.
Get-Acl : Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is not null or
empty, and then try the command again.
At line:15 char:20
+ $acl = Get-Acl $_.FullName
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Acl], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetAclCommand
You cannot call a method on a null-valued expression.
At line:21 char:9
+ $acl.SetAccessRuleProtection($isProtected, $preserveInheritance)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At line:24 char:5
+ $ACL.AddAccessRule($dirACE)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
At line:26 char:24
+ Set-Acl -aclobject $ACL -Path $folder
+ ~~~~
+ CategoryInfo : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclCommand

Access to path denied while creating new file on first iteration of loop

I have a strange problem when writing data to a new file. I have a list of files in a directory that contains data I'm parsing and returning data with the Create-VMwareconf() function. This returns the data in a hashtable that I've assigned to $t. I've pulled the desired folder and filename from the $t function however each time I begin the loop I get the following error for the initial folder creation, the second and third work fine. Interestingly enough the data that should be in the first file is present in the second folder.
If I run the script again it generates all three objects however the sequence of the of the data in the file matching the file name is incorrect.
Any help would be appreciated in how to stop the following error;
$e = (Get-Childitem ".\a\*\*.ini")
Set-Location "C:\WindowsRoot\vmwareconfigfiles\"
ForEach($d in $e){
$vmwaredirectory = New-item -type directory -path .\ -name $dd -Force
$vmwarefile = New-Item -type file -path $vmwaredirectory -name $dd -Force
$t = Create-VMwareconf($d)
$dd = $t.Value["0"]
#Write contents to new file
$t | Out-File $vmwarefile
}
Error received on initial run;
New-Item : Access to the path 'C:\WindowsRoot\vmwareconfigfiles' is denied.
At C:\WindowsRoot\parsedisrec.ps1:93 char:15
+ $vmwarefile = New-Item -type file -path $vmwaredirectory -name $dd -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\WindowsRoot\vmwareconfigfiles:String) [New- Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : NewItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand
Out-File : Cannot bind argument to parameter 'FilePath' because it is null.
At C:\WindowsRoot\parsedisrec.ps1:97 char:15
+ $t | Out-File $vmwarefile
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Out-File], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.OutFileCommand
New-Item -Type file fails during the first iteration, because $dd isn't yet initialized then, so you're trying to create a file with the same name as the current directory. You'd get the the same result if you used $null (or even .) as the name:
PS C:\> New-Item -Type file -Path 'C:\some\where' -Name $null -Force
New-Item : Access to the path 'C:\some\where' is denied.
At line:1 char:1
+ New-Item -Type file -Path 'C:\some\where' -Name $null -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\some\where:String) [New-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : NewItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand
PS C:\> New-Item -Type file -Path 'C:\some\where' -Name '.' -Force
New-Item : Access to the path 'C:\some\where' is denied.
At line:1 char:1
+ New-Item -Type file -Path 'C:\some\where' -name '.' -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\some\where\.:String) [New-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : NewItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand
Change this:
ForEach($d in $e){
$vmwaredirectory = New-item -type directory -path .\ -name $dd -Force
$vmwarefile = New-Item -type file -path $vmwaredirectory -name $dd -Force
$t = Create-VMwareconf($d)
$dd = $t.Value["0"]
into this:
ForEach($d in $e){
$t = Create-VMwareconf($d)
$dd = $t.Value["0"]
$vmwaredirectory = New-item -type directory -path .\ -name $dd -Force
$vmwarefile = New-Item -type file -path $vmwaredirectory -name $dd -Force