add-pssnapin Quest.ActiveRoles.ADManagement
$Log = Get-Date -uformat "C:\Log_%d%m%Y.log"
######################
$Date_Start = Get-Date
echo "$Date_Start : Finding Respective Site Code for All Computers....." | Out-File -Append -FilePath $Log
######################
##### Finding Respective Site Code for All Computers and Output to CSV
Function Find-Site_Move {
param ([net.ipAddress]$ip)
for ($bit = 30 ; $bit -ge 1; $bit--){
[int]$octet = [math]::Truncate(($bit - 1 ) / 8)
$net = [byte[]]@()
for($o=0;$o -le 3;$o++) {
$ba = $ip.GetAddressBytes()
if ($o -lt $Octet) {
$Net += $ba[$o]
}ELSEIF ($o -eq $octet) {
$factor = 8 + $Octet * 8 - $bit
$Divider = [math]::pow(2,$factor)
$value = $divider * [math]::Truncate($ba[$o] / $divider)
$Net += $value
}ELSE {
$Net += 0
}
}
$NetWork = [string]::join('.',$net) + "/$bit"
if ($verbose.IsPresent) {write-host -fore 'green' "Trying : $network"}
$de = New-Object directoryservices.directoryentry('LDAP://rootDSE')
$Root = New-Object directoryservices.directoryentry("LDAP://$($de.configurationNamingContext)")
$ds = New-Object directoryservices.directorySearcher($root)
$ds.filter = "(CN=$NetWork)"
$r = $ds.findone()
if ($r) {
$Site_C = $r.GetDirectoryEntry().siteObject
$2Name = "$Site_C"
$Site_Code = $2Name.split('=,')[1]
$Output= "$Computer" + ',' + "$Site_Code"
break}}
if ($Output){$Output}
else {"$Computer" + ',' + "NoSite"}
}
Function Get-Site_Move {
param ($Computer)
$ip = 0
&{TRAP{$ip = $null;continue}
$ip =[System.Net.Dns]::GetHostAddresses($Computer)
if ($ip) {
$ips = "$ip"
Find-Site_Move $ips
}ELSE {
"$Computer" + ',' + "NoSite"
}
}
}
#######################
function Split-Job {
param (
$Scriptblock = $(throw 'You must specify a command or script block!'),
[int]$MaxPipelines=10,
[switch]$UseProfile,
[string[]]$Variable,
[string[]]$Function = @(),
[string[]]$Alias = @(),
[string[]]$SnapIn
)
function Init ($InputQueue){
# Create the shared thread-safe queue and fill it with the input objects
$Queue = [Collections.Queue]::Synchronized([Collections.Queue]@($InputQueue))
$QueueLength = $Queue.Count
# Do not create more runspaces than input objects
if ($MaxPipelines -gt $QueueLength) {$MaxPipelines = $QueueLength}
# Create the script to be run by each runspace
$Script = "Set-Location '$PWD'; "
$Script += {
$SplitJobQueue = $($Input)
& {
trap {continue}
while ($SplitJobQueue.Count) {$SplitJobQueue.Dequeue()}
} |
}.ToString() + $Scriptblock
# Create an array to keep track of the set of pipelines
$Pipelines = New-Object System.Collections.ArrayList
# Collect the functions and aliases to import
$ImportItems = ($Function -replace '^','Function:') +
($Alias -replace '^','Alias:') |
Get-Item | select PSPath, Definition
$stopwatch = New-Object System.Diagnostics.Stopwatch
$stopwatch.Start()
}
function Add-Pipeline {
# This creates a new runspace and starts an asynchronous pipeline with our script.
# It will automatically start processing objects from the shared queue.
$Runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace($Host)
$Runspace.Open()
$Runspace.SessionStateProxy.SetVariable('SplitJobRunSpace', $True)
function CreatePipeline {
param ($Data, $Scriptblock)
$Pipeline = $Runspace.CreatePipeline($Scriptblock)
if ($Data) {
$Null = $Pipeline.Input.Write($Data, $True)
$Pipeline.Input.Close()
}
$Null = $Pipeline.Invoke()
$Pipeline.Dispose()
}
# Optionally import profile, variables, functions and aliases from the main runspace
if ($UseProfile) {
CreatePipeline -Script "`$PROFILE = '$PROFILE'; . `$PROFILE"
}
if ($Variable) {
foreach ($var in (Get-Variable $Variable -Scope 2)) {
trap {continue}
$Runspace.SessionStateProxy.SetVariable($var.Name, $var.Value)
}
}
if ($ImportItems) {
CreatePipeline $ImportItems {
foreach ($item in $Input) {New-Item -Path $item.PSPath -Value $item.Definition}
}
}
if ($SnapIn) {
CreatePipeline (Get-PSSnapin $Snapin -Registered) {$Input | Add-PSSnapin}
}
$Pipeline = $Runspace.CreatePipeline($Script)
$Null = $Pipeline.Input.Write($Queue)
$Pipeline.Input.Close()
$Pipeline.InvokeAsync()
$Null = $Pipelines.Add($Pipeline)
}
function Remove-Pipeline ($Pipeline) {
# Remove a pipeline and runspace when it is done
$Pipeline.RunSpace.Close()
$Pipeline.Dispose()
$Pipelines.Remove($Pipeline)
}
# Main
# Initialize the queue from the pipeline
. Init $Input
# Start the pipelines
while ($Pipelines.Count -lt $MaxPipelines -and $Queue.Count) {Add-Pipeline}
# Loop through the runspaces and pass their output to the main pipeline
while ($Pipelines.Count) {
# Only update the progress bar once a second
if (($stopwatch.ElapsedMilliseconds - $LastUpdate) -gt 1000) {
$Completed = $QueueLength - $Queue.Count - $Pipelines.count
$LastUpdate = $stopwatch.ElapsedMilliseconds
$SecondsRemaining = $(if ($Completed) {
(($Queue.Count + $Pipelines.Count)*$LastUpdate/1000/$Completed)
} else {-1})
Write-Progress 'Split-Job' ("Queues: $($Pipelines.Count) Total: $($QueueLength) " +
"Completed: $Completed Pending: $($Queue.Count)") `
-PercentComplete ([Math]::Max((100-[Int]($Queue.Count+$Pipelines.Count)/$QueueLength*100),0)) `
-CurrentOperation "Next item: $(trap {continue}; if ($Queue.Count) {$Queue.Peek()})" `
-SecondsRemaining $SecondsRemaining
}
foreach ($Pipeline in @($Pipelines)) {
if ( -not $Pipeline.Output.EndOfPipeline -or -not $Pipeline.Error.EndOfPipeline ) {
$Pipeline.Output.NonBlockingRead()
$Pipeline.Error.NonBlockingRead() | Out-Default
} else {
# Pipeline has stopped; if there was an error show info and restart it
if ($Pipeline.PipelineStateInfo.State -eq 'Failed') {
$Pipeline.PipelineStateInfo.Reason.ErrorRecord |
Add-Member NoteProperty writeErrorStream $True -PassThru |
Out-Default
# Restart the runspace
if ($Queue.Count -lt $QueueLength) {Add-Pipeline}
}
Remove-Pipeline $Pipeline
}
}
Start-Sleep -Milliseconds 100
}
}
######################
$FileName = Get-Date -uformat 'C:\AD_Data_Move_%d%m%Y.log'
get-QADComputer -searchroot "ande.in/Computers" -SizeLimit 0 | select Name `
| Split-Job -Function "Get-Site_Move","Find-Site_Move" {%{ (Get-Site_Move $_.Name) }} `
| Out-File -Append -FilePath $FileName
######################
$Date_Move = Get-Date
echo "$Date_Move : Moving Computers to Respective Site OU....." | Out-File -Append -FilePath $Log
######################
##### Moving StaleOU Computers to Location Specific Stale OU
$OU_Names = @{"SiteCode_India" = "ande.in/Asia/India/Computers";
"SiteCode_Japan" = "ande.in/Asia/Japan/Computers";
"SiteCode_Italy" = "ande.in/Europe/Italy/Computers";
"SiteCode_Canada" = "ande.in/North America/Canada/Computers";
"SiteCode_Argentina" = "ande.in/South America/Argentina/Computers";}
$Sites ='SiteCode_India','SiteCode_Japan','SiteCode_Italy','SiteCode_Canada','SiteCode_Argentina'
foreach ($Site in $Sites)
{
$SearchOU ="ande.in/Computers"
$DestOU = $OU_Names.$Site
$StaleOU = "StaleOU_$Site"
$StaleOU = get-content $FileName `
|select-object @{e={$_.split('",')[0]};n='Name'},@{e={$_.split(',"')[1]};n='Site'} `
|Where-Object {$_.Site -eq $Site}
foreach ($S in $StaleOU)
{
Get-QADComputer -SearchRoot $SearchOU -Name $S.Name | Move-QADObject -ErrorAction SilentlyContinue -NewParentContainer $DestOU
}
}
######################
$Date_Finish = Get-Date
echo "$Date_Finish : Movement Completed Successfully....." | Out-File -Append -FilePath $Log
######################