æ©å¯æ
å ±ã®æŒæŽ©ãé²ããšããäž»ãªã¿ã¹ã¯ã«å ããŠãDLPã·ã¹ãã ã«ã¯äºæ¬¡çãªïŒè¿œå ã®ïŒã¿ã¹ã¯ããããŸãã ãããã«ã¯ä»¥äžãå«ãŸããŸãã
- éä¿¡ãããã¡ãã»ãŒãžãã³ããŒããŠãå°æ¥ã®ã»ãã¥ãªãã£ã€ã³ã·ãã³ãã調æ»ããŸãã
- æ©å¯æ
å ±ã ãã§ãªããããŸããŸãªæãŸãããªããã®ïŒã¹ãã ãäžå¿«ãªè¡šçŸãæ§çãªã³ã³ãã³ãã®æ
å ±ã倧éã®ããŒã¿ãªã©ïŒãéä¿¡ããå¯èœæ§ãæé€ããŸãã
- éä¿¡æã ãã§ãªããåä¿¡æã«äžèŠãªæ
å ±ããã£ã«ã¿ãªã³ã°ããŸãã
- å人çãªç®çã§åŸæ¥å¡ãæ
å ±ãªãœãŒã¹ã䜿çšããããšãæé€ããã
- ãã©ãã£ãã¯åæžããã£ãã«è² è·ã®æé©åã
- åŸæ¥å¡ã®åŽåæéã®ç®¡çã
æåã®DLPã·ã¹ãã ã¯ãã¹ãŠã®ã¿ã¹ã¯ã解決ããã®ã§ã¯ãªãã以äžã«ã®ã¿çŠç¹ãåãããŸãã
- ãããã¯ãŒã¯äžã®ç¹å®ã®ãã¡ã€ã«ãæ€çŽ¢ããŸãã
- ã·ã¹ãã 管çè
ãŸãã¯ã»ãã¥ãªãã£æ
åœè
ãžã®å ±åããã³å ±åã
- ç¹å®ã®åºæºã«åŸã£ãŠåé€ãå®è¡ããŸãã
Windowsã§ãã¡ã€ã«ãèŠã€ããã®ã¯ç°¡åã§ç°¡åãªäœæ¥ã§ãã ãªã¢ãŒããã·ã³ã§ã®æ€çŽ¢ã§ãããããã»ã©è€éã§ã¯ãããŸããã ããããäœçŸå°ãã®ãã·ã³ã§äœããèŠã€ããå¿
èŠãããå Žåãåé¡ã¯ã©ã®ããã«ãªããŸããïŒ ãã¹ãŠã®PCãæã§æ©ããŠã¯ãããŸããã ãã®ã¿ã¹ã¯ã¯ãæ
å ±ãä¿åããããã«ç£æ»ã宿œããå¿
èŠãããå Žåãªã©ãWindows管çè
ã®äœæ¥ã§ã¯éåžžã«äžè¬çã§ãã ã¯ããå®è£
äŸã¯ãããŸãããä¿åãçŠæ¢ãããŠããããŒã¿ïŒæ ç»ãã²ãŒã ãªã©ïŒãèŠã€ããããšãç®çãšããŠããŸããç§ãææ¡ãããªãã·ã§ã³ã¯ãDLPã·ã¹ãã ã®ã¿ã¹ã¯ã®1ã€ãå®è£
ããŸãã
ããã§ãã¹ã¯ãªããã¯äœãããããšãã§ããŸããïŒãŸãã¯ãããã¹ã¯ãªããã®ã»ããïŒïŒ 管çè
ãç
©ããããæ€èšŒã®ããã«PCã®ãªã¹ããããŠã³ããŒãããªãããã«ãã¹ã¯ãªããã¯ADãšçµ±åããå¿
èŠãªæ
å ±ãååŸããŸããæ¡åŒµåãšååã§ãã£ã«ã¿ãªã³ã°ããäŸå€ã远å ãããã©ã«ããŒã«ã¬ããŒããçæãã管çè
ãšãŠãŒã¶ãŒã«ã¡ãã»ãŒãžãéä¿¡ããããšãã§ããŸãïŒéç¥ã®æ€åºå¿
èŠãªãã¡ã€ã«ãšæšå¥šäºé
ïŒã ãã©ã¡ãŒã¿ãŒãçµã¿åãããŠå€æŽããå¿
èŠãªæ©èœãååŸã§ããŸãã æ€çŽ¢åŸãæ€çŽ¢æ
å ±ãä¿åãããŠããPCã®ååãæã€ãã¡ã€ã«ã®ãªã¹ããäœæãããŸãã ã¹ã¯ãªããã®2çªç®ã®éšåã¯ãèŠã€ãã£ããã¡ã€ã«ããã¹ãŠåé€ããããç¹å®ã®åºæºã«åŸã£ãŠåé€ããããšã§ãã
ãã®ã¹ã¯ãªããã䜿çšããŠãŠãŒã¶ãŒã远跡ããäœæ¥ããã¥ã¡ã³ããç¹å®ã®å ŽæïŒããŒãœãã«ãããã¯ãŒã¯ãã©ã€ãïŒã«ä¿åããå¿
èŠãããããšãéç¥ããŸããã¹ã¯ãªããã¯PCäžã®ã¢ã¯ãã£ããŠãŒã¶ãŒãèå¥ããADããã¡ãŒã«ããã¯ã¹ã«é¢ããããŒã¿ãååŸããã©ã®ãã¡ã€ã«ãšãããèŠã€ãã£ããã«é¢ããéç¥ãéä¿¡ããŸããŠãŒã¶ãŒããããã¯ãŒã¯ã¹ãã¬ãŒãžã«ç§»åããå¿
èŠãããããŒã«ã«ãã©ã€ãäžã§åé€ããŸããããããªããšåé€ãããŸãã ãã®çµæãèŠå¶ã«åŸã£ãŠããªããã®ãåé€ããŸãã ãããã£ãŠãæ©å¯æ
å ±ã®ä¿åãå¶åŸ¡ããDLPã·ã¹ãã ã®æ©èœã®1ã€ãå®è£
ããŸãã
ãã¡ã€ã«æ€çŽ¢ã¹ã¯ãªããã¢ã«ãŽãªãºã

- ç¹å®ã®OUããã¯ãŒã¯ã¹ããŒã·ã§ã³ã®ãªã¹ããååŸããŸã
- HomePage屿§ã®ããŒã¿ããã§ãã¯ããŸããå€ããPassãã®å Žåããã¡ã€ã«ã®æ€çŽ¢ã¯ã¹ããããããŸããæ€çŽ¢ã¯ãã®ã³ã³ãã¥ãŒã¿ãŒã§æ¢ã«å®è¡ãããŠããããã§ãã
- å¯çšæ§ã確èªããŸã
- å©çšã§ããªãå Žåã¯ããã¡ã€ã«ã«æžã蟌ã¿ãŸã
- å¯èœãªå Žåããã¡ã€ã«ãæ€çŽ¢ããŸã
- æ€çŽ¢ã®æåŸã«ãHomePage屿§ã«æžã蟌ã¿ãŸã-å€ãPassã
- ãã¡ã€ã«ã¯ããã·ã³ã®ååãšæ€åºããããã¡ã€ã«ã®ãªã¹ãã§åœ¢æãããŸã
- ã¡ãã»ãŒãžãæ·»ä»ãã¡ã€ã«ä»ãã§ç®¡çè
ã«éä¿¡ãããŸã
- ããŒã«ã«ãŠãŒã¶ãŒåãæå®ããŸã
- ãŠãŒã¶ãŒã®ADã¢ãã¬ââã¹ãèªèããŸã
- ã¬ããŒãã®ã³ããŒãéä¿¡ããŸã
ãã€ãã¹ãªã»ããã¹ã¯ãªããã¢ã«ãŽãªãºã

- ADãããã·ã³ã®ãªã¹ããååŸããŸã
- notpass屿§ã®å€ãèšå®ããŸã
ãããã£ãŠããã¹ãŠã®ãã·ã³ã¯ããã§ã«ã¹ãã£ã³ããããã·ã³ãå«ããã¹ã¯ãªããåŠçã®åéã«åé¡ãããŸãã
ãã¡ã€ã«åé€ã¹ã¯ãªããã¢ã«ãŽãªãºã

- ã¹ã¯ãªããã®å
容ãããŒãããŸã
- ãªã¹ãã®åè¡ïŒçµæïŒã«ã€ããŠããªã¢ãŒãã³ã³ãã¥ãŒã¿ãŒäžã®ãªããžã§ã¯ããåé€ããŸã
ã¹ã¯ãªããã®ã»ããã¢ãããšèµ·åïŒãã¡ã€ã«ç£æ»ïŒ
ã¹ã¯ãªããã¯ãæå®ããããã©ã¡ãŒã¿ãŒã䜿çšããŠã³ãã³ããšããŠå®è¡ãããŸãã 以äžã¯ãã¹ã¯ãªãããšãã®ãã©ã¡ãŒã¿ãŒã®å®è¡äŸã§ãã Start-AuditFiles-ã¹ã¯ãªãããå®è¡ããã³ãã³ãã ã¿ã¹ã¯ã®å¿
èŠã«å¿ããŠããã©ã¡ãŒã¿ãŒãçµã¿åãããããšãã§ããŸãã
äŸ1
Start-AuditFiles -OU "OU=Test,DC=root,DC=local" -SMTP smtp.server.com -AdminMail administrator@server.com -IncludeFile *.doc,*.docx,*.sys -ExclusionFile *File1*,*File2* -ExclusionFolder â*Folder1*,*Folder2*â -ReportPath \\server\reports\ - Throttle 5
ãã®äŸã§ã¯ãOUããã³ã³ãã¥ãŒã¿ãŒãæ€çŽ¢ããŸãããã¡ã€ã«ïŒ* File1 *ã* File2 *ïŒãé€ãæ¡åŒµåïŒ* .docã*ãDocxã*ãSysïŒãæã€ãã¹ãŠã®ãã¡ã€ã«ã¯ããã£ã¬ã¯ããªïŒ* Folder1 *ã* Folder2 *ïŒãé€ããŸãã ãã¬ããŒãã¯ãã£ã¬ã¯ããªã«è€è£œãããŸãïŒ\\ server \ reports \ïŒã ã¬ããŒãã¯ãŠãŒã¶ãŒãšç®¡çè
ã«éä¿¡ãããŸãã ã¹ã¬ããã®æ°ã¯5ã§ãã
äŸ2
Start-AuditFiles -RemoteComputer ws-pc-4902,ws-pc-0982 -SMTP smtp.server.com -AdminMail administrator@server.com -Include *.doc,*.docx,*.sys -ExclusionFile *New*,*au* -AdminOnly - Throttle 10
ãã®äŸã§ã¯ãã³ã³ãã¥ãŒã¿ãŒïŒws-pc-4902ãws-pc-098ïŒããã¡ã€ã«ïŒ* File1 *ã* File2 *ïŒãé€ããã¹ãŠã®æ¡åŒµåïŒ* .docã*ãDocxã*ãSysïŒãæã€ãã¡ã€ã«ãæ€çŽ¢ããŸãã ã¬ããŒãã¯ç®¡çè
ã«ã®ã¿éä¿¡ãããŸãã ã¹ã¬ããã®æ°ã¯10ã§ãã
ã¿ãŒã²ããã³ã³ãã¥ãŒã¿ãŒã®èšå®
OU ïŒ
RemoteComputerã®æå®ã«å¿
èŠãŸãã¯å¿
èŠ ïŒ-ã¿ãŒã²ããã³ã³ãã¥ãŒã¿ãŒã®ããçµç¹åäœãžã®ãã¹ããã®ãã©ã¡ãŒã¿ãŒãæå®ãããŠããªãå ŽåãRemoteComputerãã©ã¡ãŒã¿ãŒãæå®ããå¿
èŠããããŸãã ãããã®2ã€ã®ãã©ã¡ãŒã¿ãŒã®ãããããã¹ã¯ãªããã§äœ¿çšããå¿
èŠããããŸãã
äŸïŒ-OU "OU =ãã¹ããDC =ã«ãŒããDC =ããŒã«ã«"ãŸãã¯-OU $ ComputerlistïŒå€æ°ã¯ä»ã®ã¹ã¯ãªãããšçµã¿åãããŠèšå®ãããŸãïŒã
RemoteComputer ïŒ
OUã®æå®ã«å¿
èŠãŸãã¯å¿
é ïŒ-ãªã¹ãã®ç¹å®ã®ã³ã³ãã¥ãŒã¿ãŒïŒç¹å®ã®1ã€ãŸãã¯è€æ°ã®ã³ã³ãïŒã«å¯ŸããŠã®ã¿ã¹ã¯ãªãããå®è¡ããå¿
èŠãããå Žåã«èšå®
äŸïŒ-RemoteComputer ws-pc-4902ãws-pc-0982
æ€çŽ¢ãªãã·ã§ã³
IncludeFile ïŒ
å¿
é ããã¹ã¯ã䜿çšã§ããŸã *ïŒ-æ€çŽ¢ããå¿
èŠããããã¡ã€ã«ãŸãã¯ãã®æ¡åŒµåã®ãªã¹ãïŒãªã¹ãã®å ŽåããããŸãïŒã
ExclusionFile ïŒ
ãªãã·ã§ã³ ïŒ-æ€çŽ¢ããé€å€ãããã¡ã€ã«ã®ãªã¹ãïŒãªã¹ãã®å ŽåããããŸãïŒã
ExclusionFolder ïŒ
ãªãã·ã§ã³ ïŒ-æ€çŽ¢ããé€å€ããããã£ã¬ã¯ããªã®ãªã¹ãã
ã¬ããŒããªãã·ã§ã³
ReportPath ïŒ
ãªãã·ã§ã³ ïŒ-ã¹ãã£ã³çµæãã³ããŒããããããã¯ãŒã¯ãªãœãŒã¹ãŸãã¯ããŒã«ã«ãã£ã¬ã¯ããªãžã®ãã¹ã
AdminMail ïŒ
ãªãã·ã§ã³ ïŒ-ã¬ããŒããéä¿¡ããããã®ã¢ãã¬ã¹ã管çè
å®ãŠã®ã¬ããŒãã¯åãã¢ãã¬ã¹ã«é
ä¿¡ãããŸãã
SMTP ïŒ
ãªãã·ã§ã³ ïŒ-ã¡ãã»ãŒãžãéä¿¡ããããã®ã²ãŒããŠã§ã€ãšããŠäœ¿çšãããSMTPãµãŒããŒã®ååã
AdminOnly ïŒ
ãªãã·ã§ã³ ïŒ-管çè
ã®ã¿ã«ã¬ããŒããéä¿¡ããã¢ãŒããæå¹ã«ããŸãã
ã¹ãããã« ïŒ
å¿
é ã1ã99ã®æ°å€ ïŒ-ã¹ãã£ã³ã¹ã¬ããã®æ°ãèšå®ããŸãã
ã¢ãžã¥ãŒã«ã®ã€ã³ã¹ããŒã«
ãã¡ã€ã«ããã£ã¬ã¯ããªãCïŒ\ Windows \ system32 \ WindowsPowerShell \ v1.0 \ Modulesãã«ã³ããŒããå¿
èŠããããŸãã
Invoke-Parallel.psm1
Start-AuditFiles.psm1ã¹ã¯ãªãããå®è¡ããåã«ãã¢ãžã¥ãŒã«ãã€ã³ããŒãããå¿
èŠããããŸãã
Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Invoke-Parallel.psm1 Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Start-AuditFiles.psm1
ã¹ã¯ãªããïŒã¢ãžã¥ãŒã«ïŒ
ãã®ã¹ã¯ãªããã¯ã
Invoke-Parallel.psm1ãã¡ã€ã«ãšããŠä¿åããå¿
èŠããããŸãã
ã¹ã¯ãªããInvoke-Parallel.psm1 function Invoke-Parallel { [cmdletbinding(DefaultParameterSetName='ScriptBlock')] Param ( [Parameter(Mandatory=$false,position=0,ParameterSetName='ScriptBlock')] [System.Management.Automation.ScriptBlock]$ScriptBlock, [Parameter(Mandatory=$false,ParameterSetName='ScriptFile')] [ValidateScript({test-path $_ -pathtype leaf})] $ScriptFile, [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [Alias('CN','__Server','IPAddress','Server','ComputerName')] [PSObject]$InputObject, [PSObject]$Parameter, [switch]$ImportVariables, [switch]$ImportModules, [int]$Throttle = 20, [int]$SleepTimer = 200, [int]$RunspaceTimeout = 0, [switch]$NoCloseOnTimeout = $false, [int]$MaxQueue, [validatescript({Test-Path (Split-Path $_ -parent)})] [string]$LogFile = "C:\temp\log.log", [switch] $Quiet = $false ) Begin { if( -not $PSBoundParameters.ContainsKey('MaxQueue') ) { if($RunspaceTimeout -ne 0){ $script:MaxQueue = $Throttle } else{ $script:MaxQueue = $Throttle * 3 } } else { $script:MaxQueue = $MaxQueue } Write-Verbose "Throttle: '$throttle' SleepTimer '$sleepTimer' runSpaceTimeout '$runspaceTimeout' maxQueue '$maxQueue' logFile '$logFile'" if ($ImportVariables -or $ImportModules) { $StandardUserEnv = [powershell]::Create().addscript({ $Modules = Get-Module | Select -ExpandProperty Name $Snapins = Get-PSSnapin | Select -ExpandProperty Name $Variables = Get-Variable | Select -ExpandProperty Name @{ Variables = $Variables Modules = $Modules Snapins = $Snapins } }).invoke()[0] if ($ImportVariables) { Function _temp {[cmdletbinding()] param() } $VariablesToExclude = @( (Get-Command _temp | Select -ExpandProperty parameters).Keys + $PSBoundParameters.Keys + $StandardUserEnv.Variables ) Write-Verbose "Excluding variables $( ($VariablesToExclude | sort ) -join ", ")" $UserVariables = @( Get-Variable | Where { -not ($VariablesToExclude -contains $_.Name) } ) Write-Verbose "Found variables to import: $( ($UserVariables | Select -expandproperty Name | Sort ) -join ", " | Out-String).`n" } if ($ImportModules) { $UserModules = @( Get-Module | Where {$StandardUserEnv.Modules -notcontains $_.Name -and (Test-Path $_.Path -ErrorAction SilentlyContinue)} | Select -ExpandProperty Path ) $UserSnapins = @( Get-PSSnapin | Select -ExpandProperty Name | Where {$StandardUserEnv.Snapins -notcontains $_ } ) } } Function Get-RunspaceData { [cmdletbinding()] param( [switch]$Wait ) Do { $more = $false if (-not $Quiet) { Write-Progress -Activity "Running Query" -Status "Starting threads"` -CurrentOperation "$startedCount threads defined - $totalCount input objects - $script:completedCount input objects processed"` -PercentComplete $( Try { $script:completedCount / $totalCount * 100 } Catch {0} ) } Foreach($runspace in $runspaces) { $currentdate = Get-Date $runtime = $currentdate - $runspace.startTime $runMin = [math]::Round( $runtime.totalminutes ,2 ) $log = "" | select Date, Action, Runtime, Status, Details $log.Action = "Removing:'$($runspace.object)'" $log.Date = $currentdate $log.Runtime = "$runMin minutes" If ($runspace.Runspace.isCompleted) { $script:completedCount++ if($runspace.powershell.Streams.Error.Count -gt 0) { $log.status = "CompletedWithErrors" Write-Verbose ($log | ConvertTo-Csv -Delimiter ";" -NoTypeInformation)[1] foreach($ErrorRecord in $runspace.powershell.Streams.Error) { Write-Error -ErrorRecord $ErrorRecord } } else { $log.status = "Completed" Write-Verbose ($log | ConvertTo-Csv -Delimiter ";" -NoTypeInformation)[1] } $runspace.powershell.EndInvoke($runspace.Runspace) $runspace.powershell.dispose() $runspace.Runspace = $null $runspace.powershell = $null } ElseIf ( $runspaceTimeout -ne 0 -and $runtime.totalseconds -gt $runspaceTimeout) { $script:completedCount++ $timedOutTasks = $true $log.status = "TimedOut" Write-Verbose ($log | ConvertTo-Csv -Delimiter ";" -NoTypeInformation)[1] Write-Error "Runspace timed out at $($runtime.totalseconds) seconds for the object:`n$($runspace.object | out-string)" if (!$noCloseOnTimeout) { $runspace.powershell.dispose() } $runspace.Runspace = $null $runspace.powershell = $null $completedCount++ } ElseIf ($runspace.Runspace -ne $null ) { $log = $null $more = $true } if($logFile -and $log){ ($log | ConvertTo-Csv -Delimiter ";" -NoTypeInformation)[1] | out-file $LogFile -append } } $temphash = $runspaces.clone() $temphash | Where { $_.runspace -eq $Null } | ForEach { $Runspaces.remove($_) } if($PSBoundParameters['Wait']){ Start-Sleep -milliseconds $SleepTimer } } while ($more -and $PSBoundParameters['Wait']) } if($PSCmdlet.ParameterSetName -eq 'ScriptFile') { $ScriptBlock = [scriptblock]::Create( $(Get-Content $ScriptFile | out-string) ) } elseif($PSCmdlet.ParameterSetName -eq 'ScriptBlock') { [string[]]$ParamsToAdd = '$_' if( $PSBoundParameters.ContainsKey('Parameter') ) { $ParamsToAdd += '$Parameter' } $UsingVariableData = $Null if($PSVersionTable.PSVersion.Major -gt 2) { $UsingVariables = $ScriptBlock.ast.FindAll({$args[0] -is [System.Management.Automation.Language.UsingExpressionAst]},$True) If ($UsingVariables) { $List = New-Object 'System.Collections.Generic.List`1[System.Management.Automation.Language.VariableExpressionAst]' ForEach ($Ast in $UsingVariables) { [void]$list.Add($Ast.SubExpression) } $UsingVar = $UsingVariables | Group SubExpression | ForEach {$_.Group | Select -First 1} $UsingVariableData = ForEach ($Var in $UsingVar) { Try { $Value = Get-Variable -Name $Var.SubExpression.VariablePath.UserPath -ErrorAction Stop [pscustomobject]@{ Name = $Var.SubExpression.Extent.Text Value = $Value.Value NewName = ('$__using_{0}' -f $Var.SubExpression.VariablePath.UserPath) NewVarName = ('__using_{0}' -f $Var.SubExpression.VariablePath.UserPath) } } Catch { Write-Error "$($Var.SubExpression.Extent.Text) is not a valid Using: variable!" } } $ParamsToAdd += $UsingVariableData | Select -ExpandProperty NewName -Unique $NewParams = $UsingVariableData.NewName -join ', ' $Tuple = [Tuple]::Create($list, $NewParams) $bindingFlags = [Reflection.BindingFlags]"Default,NonPublic,Instance" $GetWithInputHandlingForInvokeCommandImpl = ($ScriptBlock.ast.gettype().GetMethod('GetWithInputHandlingForInvokeCommandImpl',$bindingFlags)) $StringScriptBlock = $GetWithInputHandlingForInvokeCommandImpl.Invoke($ScriptBlock.ast,@($Tuple)) $ScriptBlock = [scriptblock]::Create($StringScriptBlock) Write-Verbose $StringScriptBlock } } $ScriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock("param($($ParamsToAdd -Join ", "))`r`n" + $Scriptblock.ToString()) } else { Throw "Must provide ScriptBlock or ScriptFile"; Break } Write-Debug "`$ScriptBlock: $($ScriptBlock | Out-String)" Write-Verbose "Creating runspace pool and session states" $sessionstate = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() if ($ImportVariables) { if($UserVariables.count -gt 0) { foreach($Variable in $UserVariables) { $sessionstate.Variables.Add( (New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList $Variable.Name, $Variable.Value, $null) ) } } } if ($ImportModules) { if($UserModules.count -gt 0) { foreach($ModulePath in $UserModules) { $sessionstate.ImportPSModule($ModulePath) } } if($UserSnapins.count -gt 0) { foreach($PSSnapin in $UserSnapins) { [void]$sessionstate.ImportPSSnapIn($PSSnapin, [ref]$null) } } } $runspacepool = [runspacefactory]::CreateRunspacePool(1, $Throttle, $sessionstate, $Host) $runspacepool.Open() Write-Verbose "Creating empty collection to hold runspace jobs" $Script:runspaces = New-Object System.Collections.ArrayList $bound = $PSBoundParameters.keys -contains "InputObject" if(-not $bound) { [System.Collections.ArrayList]$allObjects = @() } if( $LogFile ){ New-Item -ItemType file -path $logFile -force | Out-Null ("" | Select Date, Action, Runtime, Status, Details | ConvertTo-Csv -NoTypeInformation -Delimiter ";")[0] | Out-File $LogFile } $log = "" | Select Date, Action, Runtime, Status, Details $log.Date = Get-Date $log.Action = "Batch processing started" $log.Runtime = $null $log.Status = "Started" $log.Details = $null if($logFile) { ($log | convertto-csv -Delimiter ";" -NoTypeInformation)[1] | Out-File $LogFile -Append } $timedOutTasks = $false } Process { if($bound) { $allObjects = $InputObject } Else { [void]$allObjects.add( $InputObject ) } } End { Try { $totalCount = $allObjects.count $script:completedCount = 0 $startedCount = 0 foreach($object in $allObjects){ $powershell = [powershell]::Create() if ($VerbosePreference -eq 'Continue') { [void]$PowerShell.AddScript({$VerbosePreference = 'Continue'}) } [void]$PowerShell.AddScript($ScriptBlock).AddArgument($object) if ($parameter) { [void]$PowerShell.AddArgument($parameter) } if ($UsingVariableData) { Foreach($UsingVariable in $UsingVariableData) { Write-Verbose "Adding $($UsingVariable.Name) with value: $($UsingVariable.Value)" [void]$PowerShell.AddArgument($UsingVariable.Value) } } $powershell.RunspacePool = $runspacepool $temp = "" | Select-Object PowerShell, StartTime, object, Runspace $temp.PowerShell = $powershell $temp.StartTime = Get-Date $temp.object = $object $temp.Runspace = $powershell.BeginInvoke() $startedCount++ Write-Verbose ( "Adding {0} to collection at {1}" -f $temp.object, $temp.starttime.tostring() ) $runspaces.Add($temp) | Out-Null Get-RunspaceData $firstRun = $true while ($runspaces.count -ge $Script:MaxQueue) { if($firstRun){ Write-Verbose "$($runspaces.count) items running - exceeded $Script:MaxQueue limit." } $firstRun = $false Get-RunspaceData Start-Sleep -Milliseconds $sleepTimer } } Write-Verbose ( "Finish processing the remaining runspace jobs: {0}" -f ( @($runspaces | Where {$_.Runspace -ne $Null}).Count) ) Get-RunspaceData -wait if (-not $quiet) { Write-Progress -Activity "Running Query" -Status "Starting threads" -Completed } } Finally { if ( ($timedOutTasks -eq $false) -or ( ($timedOutTasks -eq $true) -and ($noCloseOnTimeout -eq $false) ) ) { Write-Verbose "Closing the runspace pool" $runspacepool.close() } [gc]::Collect() } } }
次ã®ã¹ã¯ãªããã¯ããã¡ã€ã«
Start-AuditFiles.psm1ãšããŠä¿åããå¿
èŠããããŸãã
ã¹ã¯ãªããStart-AuditFiles.psm1 $Body = ", . , . : 1) 2) . Function Start-AuditFiles { <# .Synopsis , .Description (C$ D$ .. .). : 1. OU 2. 3. 4. , 5. 6. , , 7. , .Examples 1 Start-AuditFiles -OU "OU=Test,DC=root,DC=local" -SMTP smtp.server.com -AdminMail administrator@server.com -IncludeFile *.doc,*.docx,*.sys -ExclusionFile *File1*,*File2* -ExclusionFolder *Folder1*,*Folder2* -ReportPath \\server\reports\ OU, (*.doc,*.docx,*.sys) (*File1*,*File2*), (*Folder1*,*Folder2*), (\\server\reports\) 2 Start-AuditFiles -RemoteComputer ws-pc-4902,ws-pc-0982 -SMTP smtp.server.com -AdminMail administrator@server.com -Include *.doc,*.docx,*.sys -ExclusionFile *New*,*au* -AdminOnly (ws-pc-4902,ws-pc-098), (*.doc,*.docx,*.sys) (*File1*,*File2*), .Notes OU RemoteComputer, OU , RemoteComputer .Link ... #> [CmdletBinding()] Param ( [String]$OU, [String[]]$RemoteComputer, [String[]]$ExclusionFile, [String]$ReportPath, [String]$AdminMail, [String[]]$IncludeFile, [String[]]$ExclusionFolder, [Switch]$AdminOnly = $false, [String]$SMTP, [String]$Throttle = 5 ) If (!$RemoteComputer) {$Hosts = (Get-ADComputer -Filter * -SearchBase $OU -Properties * | where { ( $PSItem.HomePage -notlike 'pass' )} ).name} else { $Hosts = $RemoteComputer } invoke-parallel -InputObject $Hosts -throttle $Throttle -ImportVariables -ScriptBlock { if(Test-Connection -ComputerName $_ -BufferSize 16 -quiet -count 2) { $Object = $_ $ErrorActionPreference = 'SilentlyContinue' $ExclusionFolder2 = $ExclusionFolder -replace ",","|" $StartTime = (Get-Date).ToString() $Hosts (Get-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName $Object | %{Get-ChildItem ('\\' + $Object + '\' + ($_.DeviceID).remove(1) + '$\*') -Include $IncludeFile -Exclude $ExclusionFile -Recurse -Force | ?{$PSItem.FullName -notmatch $ExclusionFolder2}}).FullName | Out-File -FilePath $env:TEMP\$Object.txt -Encoding unicode If (!$ReportPath) {} else {Copy-Item -Path $env:TEMP\$Object.txt -Destination $ReportPath -Force} $EndTime = (Get-Date).ToString() Write-Output ($Object) | Add-Content $env:TEMP\Online.txt Invoke-Item $env:TEMP\$Object.txt $Results = "" | Select ComputerName, "StartTime", "EndTime" $Results.ComputerName = $Object $Results.StartTime = $StartTime $Results.EndTime =$EndTime $Results If ((Get-Content $env:TEMP\$Object.txt) -eq $Null) {} else { Try { Send-MailMessage -SmtpServer $SMTP -to $AdminMail -Body $Object -From denis.pasternak@hotmail.com -Subject $Object -Attachments $env:TEMP\$Object.txt } Catch {''} If ($AdminOnly -eq $True) { Write-Host " AdminOnly - " -ForegroundColor Yellow} else { $Username=((gwmi win32_computersystem -computer $Object -ErrorAction SilentlyContinue).UserName -split '\\')[1] if($username -ne $null) { $Body = $Body $dispalyname = (Get-AdUser $username -properties DisplayName).DisplayName $email = (Get-AdUser $username -properties mail).mail sleep -Seconds 3 Send-MailMessage -SmtpServer $SMTP -Body ( ' ' + $Dispalyname + ' ' + $Body | out-string ) -To $email -From $AdminMail -Subject $Object -Attachments $env:TEMP\$Object.txt -Encoding Unicode } } } else{ } } else { (Write-Output ($Object + ' ' + (Get-Date).ToString()) | Add-Content $env:TEMP\Offline.txt)} } $OU= $null $RemoteComputer = $null $Hosts = $nul Get-Content $env:TEMP\Online.txt | Set-ADComputer -HomePage 'pass' } Function Remove-AuditFiles { [CmdletBinding(SupportsShouldProcess=$True)] Param ( [String]$TargetFile ) Get-Content -Path "$env:TEMP\$Path" | %{Remove-Item $PSItem} } Function Reset-AuditComputers { [CmdletBinding(SupportsShouldProcess=$True)] Param ( [String]$TargetOU ) Get-ADComputer -Filter * -SearchBase $TargetOU -Properties * | Set-ADComputer -HomePage 'notpass' '' | Set-Content -Path $env:TEMP\Online.txt }
ã¹ã±ãžã¥ãŒã«ãããå®è¡
ãµã³ãã«ãã£ã¬ã¯ããªcïŒ\ scriptsã«ãã¡ã€ã«ãäœæããŸãã
RunScript.ps1-ãã¡ã€ã«
ããã¹ããã³ããŒããŸãã
Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Invoke-Parallel.psm1 Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Start-AuditFiles.psm1
ãã¡ã€ã«æ€çŽ¢ã¹ã±ãžã¥ãŒã«ãäœæãã
- ã³ã³ãã¥ãŒã¿ãŒç®¡çã§ããã¿ã¹ã¯ã¹ã±ãžã¥ãŒã©ãã»ã¯ã·ã§ã³ã«ç§»åããŸãã ã¿ã¹ã¯ãäœæããç®çã®ã¿ã¹ã¯åãå
¥åããŸã
- ãæ¯æ¥ãã®é »åºŠã瀺ããŸã
- æéããæ¯æ¥ãã«èšå®ããŸã
- ãããã°ã©ã ãå®è¡ããªãã·ã§ã³ãæ®ããŸã
- ããã°ã©ã ãžã®ãã¹ã¯CïŒ\ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exeéå§åŒæ°ã¯CïŒ\ Scripts \ RunScript.ps1ã§ãã
- äœæåŸãã¿ã¹ã¯ããããã£ãéãããããªã¬ãŒãã¿ãã«ç§»åããŸã
- åžæã®ç¹°ãè¿ãé »åºŠã瀺ããã¿ã¹ã¯ãç¹°ãè¿ãããªãã·ã§ã³ãèšå®ããŸã
- ããã¹ãŠã®ãŠãŒã¶ãŒã«å¯ŸããŠå®è¡ãããã³ãæé«ã®åªå
床ã§å®è¡ããªãã·ã§ã³ãèšå®ããŸãã ãªã¢ãŒãã³ã³ãã¥ãŒã¿ãŒäžã®ãã¹ãŠã®ãã¡ã€ã«ãèªã¿åãæš©éãæã€ãŠãŒã¶ãŒãæå®ããŸãã éåžžããããã¯ãªã¢ãŒãã³ã³ãã¥ãŒã¿ãŒã®Adââministratorsã°ã«ãŒãã®ã¡ã³ããŒã§ãããŠãŒã¶ãŒã§ãã
çµæãšäœæ¥ãã¡ã€ã«ã«é¢ããæ
å ±
ã¹ã¯ãªããã¯ãã¹ãã£ã³çµæãïŒ
TEMPïŒ
ãã£ã¬ã¯ããªã«ä¿åããŸãã äŸã§ã¯ããã®ãã£ã¬ã¯ããªã¯CïŒ\ Users \ Administrator \ AppData \ Local \ Tempã§ãã ã³ã³ãã¥ãŒã¿ãŒã䜿çšå¯èœã§ããã¡ã€ã«ãèŠã€ãã£ãå Žåãçµæãå«ããã¡ã€ã«ãäœæãããŸãã ã³ã³ãã¥ãŒã¿ãŒã䜿çšã§ããªãå Žåãããã«é¢ããæ
å ±ãoffline.txtãã¡ã€ã«ã«è¿œå ãããŸãã

èŠã€ãã£ããã¡ã€ã«ãåé€ãã
PowerShellãèµ·åããŠã³ãã³ããå®è¡ããŸãã
Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Start-AuditFiles.psm1 Remove-AuditFiles Remove-AuditFiles - TargetFile ws-9281.txt,ws-8721.txt
Remove-AuditFiles-ãã¹ãŠã®æ€çŽ¢çµæãæ€çŽ¢ããåçµæãåŠçããåŸããã¡ã€ã«ãåé€ããŸãã
ç¹å®ã®ãã¡ã€ã«ïŒç¹å®ã®ã³ã³ãã¥ãŒã¿ãŒïŒãæå®ã§ããŸããäŸïŒ
Remove-AuditFiles-TargetFile ws-9281.txtãws-8721.txt
ã¹ãã£ã³ããã³ã³ãã¥ãŒã¿ãŒã®ãªã¹ãããªã»ãããã
PowerShellãèµ·åããŠã³ãã³ããå®è¡ããŸãã
Reset-AuditComputerså®è¡åŸãæå®ãããOUã®ã³ã³ãã¥ãŒã¿ãŒã¯ã¹ãã£ã³ãããŠããªããã®ãšããŠããŒã¯ãããŸãã
Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Start-AuditFiles.psm1 Reset-AuditComputers - TargetOU OU "OU=Test,DC=root,DC=local"
ã¹ã¯ãªããã®èª¬æ$ Body倿°-ã¡ãã»ãŒãžã®æ¬æã«æ¿å
¥ãããããã¹ããå«ãŸããŸãã å°æ¥ããã®ããã¹ãã¯ãšã³ããŠãŒã¶ãŒã«æçŽã§éãããŸãã
$Body = ", . , . : 1) 2) .
掟çåStart-AuditFilesãäžãããã颿°ã®å§ãŸãïŒ
Function Start-AuditFiles {
ãã«ãããã¹ãã䌎ãã¹ã¯ãªããã®èª¬æã ãGet-Help Start-AuditFilesãã䜿çšããŠããã«ãã䜿çšããäŸãšæ§æã«é¢ããæ
å ±ãååŸã§ããŸãã
<
颿°ã§å°æ¥äœ¿çšãã倿°ã«ã€ããŠèª¬æããŸãã
$ OU-Active Directoryã®çµç¹åäœãžã®ãã¹
$ ExclusionFile-æ€çŽ¢ããé€å€ããããã¡ã€ã«ã®ãªã¹ã
$ ReportPath-ã¬ããŒããè€è£œããããã£ã¬ã¯ããªãžã®ãã¹
$ AdminMail-ã¬ããŒãã®éä¿¡å
ããã³ç®¡çè
åãã®ã³ããŒã®éä¿¡å
ã®ç®¡çè
ã®é»åã¡ãŒã«ã¢ãã¬ã¹
$ IncludeFile-æ€çŽ¢ããããã¡ã€ã«æ¡åŒµåãŸãã¯ãã¡ã€ã«å
$ ExclusionFolder-æ€çŽ¢ããé€å€ããããã©ã«ããŒã®ãªã¹ã
$ AdminOnly-ã¬ããŒãã管çè
ã®ã¿ã«éä¿¡ãããã©ãããåçãããã©ã¡ãŒã¿ãŒ
$ SMTP-SMTPãµãŒããŒã®ã¢ãã¬ã¹ãŸãã¯åå
$ã¹ãããã«-䞊åã¹ã¬ããã®æ°ã
[CmdletBinding()] Param ( [String]$OU, [String[]]$RemoteComputer, [String[]]$ExclusionFile, [String]$ReportPath, [String]$AdminMail, [String[]]$IncludeFile, [String[]]$ExclusionFolder, [Switch]$AdminOnly = $false, [String]$SMTP, [String]$Throttle = 5 )
ãRemoteComputerãããŒã䜿çšãããå Žåããã§ãã¯ãå®è¡ãããŸãããã®å Žåãã¹ãã£ã³ã¯ç¹å®ã®ïŒæå®ãããïŒã³ã³ãã¥ãŒã¿ãŒã§ã®ã¿è¡ããããOUãããŒãæå®ãããå Žå-ãã®å Žåãªã¹ãã¯æå®ãããOU ADããååŸãããHomePage屿§ãæã€ã³ã³ãã¥ãŒã¿ãŒãéžæãããŸãããã¹ãïŒããã¯ãæ¢ã«æ€çŽ¢ããããã·ã³ã§æ€çŽ¢ãç¹°ãè¿ãããã®ãé²ãããã«è¡ãããŸãïŒã
If (!$RemoteComputer) {$Hosts = (Get-ADComputer -Filter * -SearchBase $OU -Properties * | where { ( $PSItem.HomePage -notlike 'pass' )} ).name} else { $Hosts = $RemoteComputer }
ã¹ã¯ãªããå®è¡ã®éå§ããã¹ãå€ãããã³ã¹ã¬ããæ°ã眮ãæããããŸãã
invoke-parallel -InputObject $Hosts -throttle $Throttle -ImportVariables -ScriptBlock {
ãããã¯ãŒã¯äžã®ã³ã³ãã¥ãŒã¿ãŒã®å¯çšæ§ã確èªããŸãã
if(Test-Connection -ComputerName $_ -BufferSize 16 -quiet -count 2) {
æ€çŽ¢ã®å®è¡ã«å¿
èŠãªå€æ°ã®å€ã¯ãäžèšã®å€æ°ããååŸãããŸãã æ€çŽ¢ã®éå§ã¯èšæ¶ãããŸãã
$Object = $_ $ErrorActionPreference = 'SilentlyContinue' $ExclusionFolder2 = $ExclusionFolder -replace ",","|" $StartTime = (Get-Date).ToString() $Hosts
æ€çŽ¢ã®å®è¡ïŒ
- ç©çãã£ã¹ã¯ã®ãªã¹ãã®ååŸïŒGet-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName $ ObjectïŒ
- UNCãã¹ã¯ãã©ã€ãæåïŒGet-ChildItemïŒ '\\' + $ Object + '\' +ïŒ$ _ãDeviceIDïŒ.removeïŒ1ïŒ+ '$ \ *'ïŒã§åœ¢æãããŸã
- å«ãŸãããªããžã§ã¯ããšé€å€ã®æ€çŽ¢ã®ããŒã瀺ããŸãïŒ-Include $ IncludeFile -Exclude $ ExclusionFile -Recurse -ForceïŒ
- , (?{$PSItem.FullName -notmatch $ExclusionFolder2}}).FullName)
- (Out-File -FilePath $env:TEMP$Object.txt -Encoding unicode)
(Get-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName $Object | %{Get-ChildItem ('\\' + $Object + '\' + ($_.DeviceID).remove(1) + '$\*') -Include $IncludeFile -Exclude $ExclusionFile -Recurse -Force | ?{$PSItem.FullName -notmatch $ExclusionFolder2}}).FullName | Out-File -FilePath $env:TEMP\$Object.txt -Encoding unicode
, «ReportPath», .
If (!$ReportPath) {} else {Copy-Item -Path $env:TEMP\$Object.txt -Destination $ReportPath -Force}
.
$EndTime = (Get-Date).ToString()
, .
Write-Output ($Object) | Add-Content $env:TEMP\Online.txt
, , .
Invoke-Item $env:TEMP\$Object.txt $Results = "" | Select ComputerName, "StartTime", "EndTime" $Results.ComputerName = $Object $Results.StartTime = $StartTime $Results.EndTime =$EndTime $Results
, , ( ), . .
If ((Get-Content $env:TEMP\$Object.txt) -eq $Null) {}
, SMTP , , , .
else { Try { Send-MailMessage -SmtpServer $SMTP -to $AdminMail -Body $Object -From denis.pasternak@hotmail.com -Subject $Object -Attachments $env:TEMP\$Object.txt } Catch {''}
, , .
If ($AdminOnly -eq $True) { Write-Host " AdminOnly - " -ForegroundColor Yellow} else
.
{ $Username=((gwmi win32_computersystem -computer $Object -ErrorAction SilentlyContinue).UserName -split '\\')[1] if($username -ne $null)
, Active Directory, Email. Active Directory.
{ $Body = $Body $dispalyname = (Get-AdUser $username -properties DisplayName).DisplayName $email = (Get-AdUser $username -properties mail).mail sleep -Seconds 3
, $Body Active Directory.
Send-MailMessage -SmtpServer $SMTP -Body ( ' ' + $Dispalyname + ' ' + $Body | out-string ) -To $email -From $AdminMail -Subject $Object -Attachments $env:TEMP\$Object.txt -Encoding Unicode
, , .
} } } else{ } } else { (Write-Output ($Object + ' ' + (Get-Date).ToString()) | Add-Content $env:TEMP\Offline.txt)} }
.
$OU= $null $RemoteComputer = $null $Hosts = $nul
«HomePage» Active Directory. , .
Get-Content $env:TEMP\Online.txt | Set-ADComputer -HomePage 'pass' }
, , ( ), . $TargetFile â .
Function Remove-AuditFiles { [CmdletBinding(SupportsShouldProcess=$True)] Param ( [String]$TargetFile ) Get-Content -Path "$env:TEMP\$Path" | %{Remove-Item $PSItem} }
HomePage Active Directory. OU. -.
Function Reset-AuditComputers { [CmdletBinding(SupportsShouldProcess=$True)] Param ( [String]$TargetOU ) Get-ADComputer -Filter * -SearchBase $TargetOU -Properties * | Set-ADComputer -HomePage 'notpass' '' | Set-Content -Path $env:TEMP\Online.txt }