Issue passing a variable through a Powershell script - powershell

Trying to create a powershell script to perform the following tasks:
- Asks for a username to use when creating folder and assigning permissions
- Create folder on our NAS with that username for a name
- Create DFS folder with same name and assign it a target path
- Assign explicit permissions for the user to that DFS folder
My script looks like the following:
$Username = read-host "Type Username"
#Create new folder on the NAS and set necessary permissions
New-Item -Path \\NAS\USER_SHARE\$Username -ItemType Directory
#Create new DFS folder and target
New-DfsnFolder -Path "\\DOMAIN.local\user\$Username" -TargetPath "\\NAS\USER_SHARE\$Username"
#Assign explicit permissions to DFS folder for user
dfsutil property SD grant \\DOMAIN.local\user\$Username DOMAIN\$Username:F protect
It performs everything but the last line. It creates the DFS folder but doesn't give permissions. No error message is given, just prints out the help info for the dfsutil command. When I run the last line independently with a static username, it is successful. So I believe there is something with the syntax of the $Username:F part of that last line of code messing it up.
How can I separate that last section to make this work?

Try the invoke operator: &. Also, your variable call to $Username is going to cause issues with the colon, so you want to use {} around the variable name.
$Params = #('property','SD','grant',
"\\DOMAIN.local\user\$Username",
"DOMAIN\${Username}:F",
'protect')
& dfsutil #Params

Related

if then else not seeing else argument

I'm trying to learn myself some PowerShell scripting to automate some tasks at work.
The latest task I tried to automate was to create a copy of user files to a network-folder, so that users can easily relocate their files when swapping computers.
Problem is that my script automatically grabs the first option in the whole shebang, it never picks the "else"-option.
I'll walk you through part of the script. (I translated some words to make it easier to read)
#the script asks whether you want to create a copy, or put a copy back
$question1 = Read-Host "What would you like to do with your backup? make/put back"
if ($question1 -match 'put back')
{Write-Host ''
Write-Host 'Checking for backup'
Write-Host ''
#check for existing backup
if (-Not(Test-Path -Literalpath "G:\backupfolder"))
{Write-Host "no backup has been found"}
Elseif (Test-Path -LiteralPath "G:\backupfolder")
{Write-Host "a backup has been found."
Copy-Item -Path "G:\backupfolder\pictures\" -Destination "C:\Users\$env:USERNAME\ ....}}
Above you see the part where a user would want the user to put a "backup" back.
It checks if a "backup" exists on the G-drive. If the script doesn't see a backup-folder it says so. If the script DOES see the backup it should copy the content from the folders on the G-drive to the similarly named folder you'd find on the user-profile-folder. Problem is: So far it only acts as if there is never a G:\backupfolder to be found. It seems that I'm doing something wrong with if/then/else.
I tried with if-->Else, and with if-->Elseif, but neither works.
I also thought that it could be the Test-Path, so I tried adding -LiteralPath, but to no avail.
There is more to the script but it's just more if/then/else. If I can get it to work on this part I should be able to get the rest working. What am I not seeing/doing wrong?

Using PowerShell to grant access to a folder for an "IIS AppPool"

I Writing a script to automate the deployment of my platform but i cant figure out how to set an app pool to have the permissions with the code i have below it just inserts the text below with the app pool name. I assume this is because this is a frendily name and when you click check names normally it will fetch the correct user but i cant figure out hot to do this in powershell.
function Set_iis_perms {
param (
[parameter(position=0)]
$AppPoolName,
[parameter(position=1)]
$FileName
)
$acl = Get-Acl $FileName
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(("iis apppool\$Apppool_Name"),"Modify","Allow")))
$acl | Set-Acl $FileName
}
Even if someone can point me in the right direction i would be most thankful.
Kind Regards
Dom
Setting ACL via Get/Set-ACL and icacls is a really common thing and covered in many resources. Example(s):
Setting ACL on folder or file using PowerShell
This script will set folder permission on a folder (c:\1 and C:2) and
its sub folder. If the folder does not exist, it will create the
folder, set as shared and add the groups to the folder. Group_Name
has to be replaced with Actual Group.
Application Pool Identities
Setting permissions for ASP.NET application on IIS with
PowerShell
As per this StackOverflow Q&A
How can I add ACL permissions for IIS APPPOOL* accounts via
Powershell?
Set-Acl $directory $acl $user = New-Object
System.Security.Principal.NTAccount("$domain\\$username")
UPDATE: Seems that it won't accept the "IIS APPPOOL\AppPoolName" as an
NTAccount identifier. Now, there are two ways to accomplish what you
are trying to do:
Create a new SID object with the AppPoolIdentities SID and translate
it into an NTAccount, like this:
http://iformattable.blogspot.com/2007/12/convert-sid-to-ntaccount-with.html,
and you should be able to treat it like any other NTAccount object. If
you still want to be able to pass domain/usernames for real accounts,
built in some simple logic that defaults to the AppPool SID if
username is "AweSomeAppPool" and domain is empty, just as an example.
Use PowerShell to invoke icacls.exe, and use it to grant/revoke
whatever permissions you want, like this (first normal icacls form
command prompt, then powershell, notice the difference):
icacls.exe test.txt /grant "IIS AppPool\DefaultAppPool":(OI)(CI)M
cmd /c icacls test.txt /grant "IIS AppPool\DefaultAppPool:(OI)(CI)M"

Calling file from remote directory using powershell

I have a basic powershell script that runs great in its local directories. I am very new to powershell so this may be a basic question. The csv file really will sit in the following directory \ADdata.acdsd.internal\F\Exports\Google\Student Accounts. How do I reference this directory in my code below. Do I need to replace the $list command with some other command.
$list = Import-Csv studentaccounts.csv
foreach ($entry in $list)
{
C:\gam-rcsdkids\gam.exe create user $($entry.newuser) firstname $($entry.firstname) lastname $($entry.lastname) password $($entry.password)
}
PowerShell supports UNC paths without problems, so first of all try to invoke:
cd \\ADdata.acdsd.internal\F\Exports\Google\Student Accounts\
If above command works you should call below line to import CSV:
$list = Import-Csv \ADdata.acdsd.internal\F\Exports\Google\Student Accounts\
Now why I started with cd: because if there is a problem with accessing share you will see better in cd command (there won't be errors about csv file)

Adding computer to Event Log Readers group using Powershell Commands

I need to add the computer to the Event Log Readers group. I had tried the below script.
$hostName = "Hostname"
$computername = $env:computername
$EventLogGroup = [adsi]"WinNT://$computername/Event Log Readers,group"
$temp = "WinNT://$hostName"
$EventLogGroup.Add($temp)
The same script worked for adding the user to group and for adding the computers its not adding.
Object types we need to change to Computers I think. Locations will be in same domain.
Any modifications or alternative script will be helpful
"A member could not be added to or removed from the local group because the member does not exist" this is the error I am getting while executing the script
Try to add the domain name and a dollar sign after the computer name:
$temp = "WinNT://DomainName/$hostName$,computer"

Determine where script is being executed from

I have a script that will send items to the recycle bin (if selected) or delete items permanently. If the script is run locally, the recycle piece works properly.
However, if it's run from a different computer - in this case, my local machine runs the script against a shared folder on a server - the delete is permanent, and doesn't get sent to the recycle bin. The script (in a prior run) makes a decision about WHAT to delete by first setting the Archive bit to TRUE and then (after seeing how many backups it is to retain) un-setting the Archive bit for items to be deleted on the next execution of that same script.
My thought was to alter the main script to mark the files for deletion, but only do the physical action of deleting the file(s) only when the script was being run locally, or to put the Recycle script (by itself) as a Task on the server that would delete & send the item to the Recycle Bin that would run at a set interval.
My questions-
In Powershell (using 2.0) how do you determine the source computer
vs the target computer? In this case, the script is being run from
MyPC, and it's target is Server1.
The script will run whether the target is a mapped drive (Drive Y:),
or if it's targeted by the servername (\Server1). How can you
distinguish the above question in both of these cases?
You can get the local computer name with $env:COMPUTERNAME. Use it to compare the value against the target server name.
For each file, you'd have to check first if the drive is a mapped drive, if it is, get the server name from the wmi instance and compare it to $env:COMPUTERNAME.
You can get a file's Drive qualifier with the Split-Path cmdlet:
PS> $drive = Split-Path Q:\test.txt -Qualifier
PS> $drive
Q:
And then get the server name with WMI:
PS> (gwmi win32_logicaldisk -filter "drivetype=4 and deviceid='$drive'").ProviderName.Split('\')[2]
Server1
The OP wrote:
#Shay - Thanks for your help. I've learned a great deal from many posts by you on various Powershell sites.
I was able to use almost everything you suggested, and only had to add an extra line of code to make it work. I checked the property ([System.Uri]$markedFile).IsUnc to determine if the filename I've read is a UNC name.
It returns False if the drive is mapped, and True if it is UNC. From that, I'm able to get the servername & make a comparison to the environment. Code follows.
$markedFile = "\\Server1\foldername1\Error.log"
#$markedFile = "Y:\foldername1\Error.log"
$TargetComputer = $null
$thisComputer = Get-Content env:computername
if (Test-Path $markedFile) { # if file exists
if (([System.Uri]$markedFile).IsUnc) { # if it's a UNC name & not a mapped drive name
$TargetComputer = ([System.Uri]$markedFile).Host
}
else { #file is not a UNC name, it must be a mapped drive
$drive = Split-Path $markedFile -Qualifier
$TargetComputer = (gwmi win32_logicaldisk -Filter "drivetype=4 and deviceid = '$drive'").Providername.split('\')[2]
}
}
The above code works either way. Thank you again for your help!