Wednesday, February 25, 2015

Using PSEXEC to execute powershell scripts remotely

I ran into an issue where I found myself having to hit the any key to complete a psexec call to a batch file that launches powershell. The workaround was to add -inputformat none to my launch parameters for powershell.

example: powershell -inputformat none -file C:\scripts\StampBackups.ps1 -executionpolicy bypass 

ref http://stackoverflow.com/questions/4238192/running-powershell-from-msdeploy-runcommand-does-not-exit/4239192#4239192

ref https://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected

Monday, February 9, 2015

Migrate tons of groups and users

So I had to create a bunch of local groups and populate them with accounts from active directory as determined by a query on the server I was migrating from. There was probably a hundred groups defined, with tons of users in each. 2 scripts to get this done, sure I could spend more time to consolidate into one but time was of the essence. Please test, I'm not responsible for your environment. Script 1. I used this to collect the info. I found this out on the web, I forgot who created it otherwise I'd give them credit. I did modify it further suit my needs. Trap {"Error: $_"; Break;} Function EnumLocalGroup($LocalGroup) { $Group = [ADSI]"WinNT://$strComputer/$LocalGroup,group" "Group: $LocalGroup" # Invoke the Members method and convert to an array of member objects. if (($LocalGroup -ne "HelpServicesGroup" -or $localgroup -ne "Guests")){ $Members= @($Group.psbase.Invoke("Members")) $Collection = @() ForEach ($Member In $Members) { $path = $Member.GetType().InvokeMember("Parent", 'GetProperty', $Null, $Member, $Null) $Name = $Member.GetType().InvokeMember("Name", 'GetProperty', $Null, $Member, $Null) $collection += "$LocalGroup;$path/$Name" } $collection|Out-File -FilePath $filepath -Append } } # Specify the computer. $strComputer = (Read-Host "What Computer") "Computer: $strComputer" #specify the file path $filepath = (Read-Host "File path to export results to" $computer = [adsi]"WinNT://$strComputer" $objCount = ($computer.psbase.children | measure-object).count $i=0 foreach($adsiObj in $computer.psbase.children) { switch -regex($adsiObj.psbase.SchemaClassName) { "group" { $group = $adsiObj.name EnumLocalGroup $group } } #end switch $i++ } #end foreach Script 2. Reads CSV and breaks it out $PATH = (read-host "Please type the file path to your semi-colon delimited file") $groupsNusers = Import-Csv -Path $PATH -Delimiter ';' $remotecomputer = (read-host "Please enter the computername"") foreach ($strCollection in ($groupsNusers)){ $localgroup = $strCollection.group $aduser=$strCollection.user.ToString().Replace("\","/") try { $user = [ADSI]("WinNT://$aduser") $New = [ADSI]"WinNT://$remotecomputer" #create groups $NEWgroup = $NEW.Create("Group","$LocalGroup") $NEWgroup.setinfo() $objGroup = [ADSI]"WinNT://$remotecomputer/$LocalGroup,group" $objGroup.PSBase.Invoke("Add",$User.PSBase.Path) } Catch [System.Management.Automation.MethodInvocationException] { if ($_.Exception.HResult -eq "-2146233087") {write-host "$aduser is already in $localgroup";continue} else {Write-Error "Unhandled error:" + $_.exception;Break} } Catch {Write-Error $_} } $PATH = "" $groupsNusers = "" $aduser="" $localgroup=""