Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 129
  • Last Modified:

powershell help

Hi,
I have the following script and it works. I am new to powershell. Could you please modify it so that I can add more than one trustee using input file or comma separated values. I tried to add more than one trustee - for example -trustee domain\user1, domain\user2 but it doesn't accept more than one value.

EXAMPLE   
.\Get-Set-ADAccountasLocalAdministrator.ps1.ps1 -Computer 'Server01,Server02' -Trustee Contoso\HRManagers

.EXAMPLE   
.\Set-ADAccountasLocalAdministrator.ps1 -InputFile C:\ListofComputers.txt -Trustee User01

param(
    [Parameter(ParameterSetName='InputFile')]
    [string]
        $InputFile,
    [Parameter(ParameterSetName='Computer')]
    [string]
        $Computer,
    [string]
        $Trustee
)
<#
.SYNOPSIS
    Function that resolves SAMAccount and can exit script if resolution fails
#>
function Resolve-SamAccount {
param(
    [string]
        $SamAccount,
    [boolean]
        $Exit
)
    process {
        try
        {
            $ADResolve = ([adsisearcher]"(samaccountname=$Trustee)").findone().properties['samaccountname']
        }
        catch
        {
            $ADResolve = $null
        }

        if (!$ADResolve) {
            Write-Warning "User `'$SamAccount`' not found in AD, please input correct SAM Account"
            if ($Exit) {
                exit
            }
        }
        $ADResolve
    }
}

if (!$Trustee) {
    $Trustee = Read-Host "Please input trustee"
}

if ($Trustee -notmatch '\\') {
    $ADResolved = (Resolve-SamAccount -SamAccount $Trustee -Exit:$true)
    $Trustee = 'WinNT://',"$env:userdomain",'/',$ADResolved -join ''
} else {
    $ADResolved = ($Trustee -split '\\')[1]
    $DomainResolved = ($Trustee -split '\\')[0]
    $Trustee = 'WinNT://',$DomainResolved,'/',$ADResolved -join ''
}

if (!$InputFile) {
	if (!$Computer) {
		$Computer = Read-Host "Please input computer name"
	}
	[string[]]$Computer = $Computer.Split(',')
	$Computer | ForEach-Object {
		$_
		Write-Host "Adding `'$ADResolved`' to Administrators group on `'$_`'"
		try {
			([ADSI]"WinNT://$_/Administrators,group").add($Trustee)
			Write-Host -ForegroundColor Green "Successfully completed command for `'$ADResolved`' on `'$_`'"
		} catch {
			Write-Warning "$_"
		}	
	}
}
else {
	if (!(Test-Path -Path $InputFile)) {
		Write-Warning "Input file not found, please enter correct path"
		exit
	}
	Get-Content -Path $InputFile | ForEach-Object {
		Write-Host "Adding `'$ADResolved`' to Administrators group on `'$_`'"
		try {
			([ADSI]"WinNT://$_/Administrators,group").add($Trustee)
			Write-Host -ForegroundColor Green "Successfully completed command"
		} catch {
			Write-Warning "$_"
		}        
	}
}

Open in new window

0
creative555
Asked:
creative555
  • 3
  • 2
2 Solutions
 
oBdACommented:
You can just call the script in a ForEach loop; inside the loop, the variable with the value currently being processed will be "$_".
So you'll read a file with the trustee names, pipe that to ForEach-Object ("%" is an alias for this), and wherever you want the name from the trustee file appear, you use $_
Get-Content C:\Temp\Trustees.txt | % {.\Set-ADAccountasLocalAdministrator.ps1 -Computer 'Server01,Server02' -Trustee $_}

Open in new window

0
 
QlemoC++ DeveloperCommented:
That has been my first thought, too, but its getting very unefficient for a list of machines. Also, the code is a little cumbersome.
0
 
QlemoC++ DeveloperCommented:
This is what I would use (untested!).
function Set-ADAccountAsLocalAdministrator(
  [string]   $InputFile,
  [string[]] $Computer,
  [string[]] $Trustee
)
{
  <#
  .SYNOPSIS
    Assigns user or groups to the local Administrators group

  .EXAMPLE   
    Set-ADAccountasLocalAdministrator -Computer Server01,Server02 -Trustee Contoso\HRManagers,Contoso\ITAdministrators

  .EXAMPLE
    Set-ADAccountasLocalAdministrator -InputFile C:\ListofComputers.txt -Trustee User01
  #>

  <#
  .SYNOPSIS
    Function that resolves SAMAccount and can exit script if resolution fails
  #>

  function Resolve-SamAccount ([string]  $SamAccount)
  {
    try   { ([adsisearcher]"(samaccountname=$Trustee)").findone().properties['samaccountname'] }
    catch { Write-Warning "User `'$SamAccount`' not found in AD, please input correct SAM Account" }
  }



  if ($InputFile)
  {
    if (!(Test-Path -Path $InputFile)) {
      Write-Warning "Input file not found, please enter correct path"
      exit
    }
    $Computer = Get-Content $InputFile
  }

  if (!$Computer) { $Computer = Read-Host "Please input computer name" }
  if (!$Trustee)  { $Trustee  = Read-Host "Please input trustee"       }



  $ADObjs = @()
  foreach ($obj in $Trustee)
  {
    if ($obj -notmatch '\\') {
      $ADResolved  = Resolve-SamAccount -SamAccount $obj
      $DomResolved = $env:UserDomain
    } else {
      $DomResolved, $ADResolved = $obj -split '\\'   
    }
    if ($ADResolved)
    {
      $ADObs += New-Object PsObject -Property @{
        Obj = [ADSI] ("WinNT://$DomResolved/$ADResolved") 
        Res = $ADResolved
      }  
    }
  }

  foreach ($pc in $Computer)
  {
    $localgrp = [ADSI]"WinNT://$pc/Administrators,group"
    foreach ($adobj in $ADObjs)
    {
      Write-Host "Adding '$($adobj.Res)' to Administrators group on '$pc'"
      try   { $localgrp.Add($adobj.Obj) }
      catch { Write-Warning "failed" }
    }
  }
}

Open in new window

You need to dot-source the script once for the current PS session, then run it with your parameters, like (the name of the script doesn't matter anymore, but I'll use the full name):
. c:\Scripts\Set-ADAccountAsLocalAdministrator.ps1
Set-ADAccountAsLocalAdministrator -Computer pc1, pc2 -Trustee dom\usr1, dom\grp1

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
creative555Author Commented:
Hello,
thank you so much!
This works great now with foreach loop! Also, I tried the revised script but it is missing parentheses somewhere. Could you pls paste it again.


 I am getting an error for the remote computers....WARNING: The following exception occurred while retrieving member "add": "The network path was not found

I wonder if we can use remote-powershelling here and invoke-command somehow.

powershell remoting is enabled and all computers are 2012. I was listening to youtube video and they say it is the best to use it for remote computers.

https://www.youtube.com/watch?v=WUgbMKOhShg

if I do this:
invoke-command pc01,pc02,pc02 {get-eventlog -logname } etc I don't get error about network path....but for this current script I do.....

Can we use invoke command with this script? what would be the command?
0
 
creative555Author Commented:
oh hey,

actually i tried this below but still get network not found error. I am having issue with pinging those computers. it is  timing out. not sure if smth is blocking ping requests but script is working!!


invoke-command {Get-Content C:\CFscript2\Trustee.txt | % {.\Set-ADAccountasLocalAdministrator.ps1 -Computer 'tworker01,worker02.testtarget.local' -Trustee $_}}

thank you so much!
0
 
creative555Author Commented:
both solutions are great!! I could pick only one best answer. thank you so much!
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now