Powershell: рекурсивно установить наследование профилей, а также удалить старые профили

Сценарий: у нас есть перемещаемые профили на работе. Во время нашего обновления клиентских машин с XP до Win7 подпапка Win7.v2 не создается с установленным флагом наследования (незначительная проблема легко решается). Кроме того, у нас также есть множество старых профилей (winxp, winxp.old, winxp_old, winxp_, win7.v2_old и т. Д.), Которые необходимо удалить. Я придумал скрипт, чтобы попытаться сделать это, но застрял на удалении старых профилей.

Среда: перемещаемые профили имеют следующий формат:

  • P: \ Profiles $ \ User1 \ WIN7.V2
  • P: \ Profiles $ \ User1 \ WinXP
  • P: \ Proifles $ \ User1 \ WIN7.V2_old
  • ...

Я самоучка, поэтому извиняюсь за скриптовку мусора. Я еще не использовал переменную $date, но постараюсь не удалять ни одной папки, которая была изменена за последние 10 дней.

cls
# Date and time script is started
$StartDate = date

# Date variable for 30 day buffer
$date = (Get-Date).AddDays(-30)

# Sets path and log variables
$ProfilePath = "D:\Work\Profiles"
$LogPath = "D:\Work\Logs"
$Takeownlog = "$LogPath\Takeown.log"
$Icaclslog = "$LogPath\icacls.log"
$NoWIN7FolderLog = "$LogPath\NoWin7Folder.log"

# Deletes any previous log entries
del $Takeownlog
del $Icaclslog
del $NoWIN7FolderLog

# Gets Subfolder list
$FolderList = Get-ChildItem $ProfilePath

# Main body of script. 
foreach ($SubFolder in $FolderList)
{
$winxp = "$ProfilePath\$subfolder\winxp"
$winos = "$ProfilePath\$subfolder\%winos%"
$winvar = "$ProfilePath\$subfolder\win"
   # Checks if the WIN7.V2 folder exists. If it doesn't, it logs it and moves to next folder
    if(-not(Test-Path -path $ProfilePath\$SubFolder\WIN7.V2)){
        Write-Host "$SubFolder\WIN7.V2 does not exist. Moving on..." -ForegroundColor Red
        Write-Output "$ProfilePath\$SubFolder\WIN7.V2 does not exist" | Out-File  $NoWIN7FolderLog -Append -encoding default
        } Else
    {
    # If the WIN7.V2 folder does exist it will recursively set Ownership to Administrators and then set the inheritance on the WIN7.V2 folder
        Write-Host "Fixing ownership and inheritance: $ProfilePath\$SubFolder" -foregroundcolor Green
        Write-Output "Fixing ownership and ineritance: $ProfilePath\$SubFolder\WIN7.V2" | Out-File $Takeownlog -append -encoding Default
        takeown /f $ProfilePath\$SubFolder\WIN7.V2 /A /R /D Y | Out-File $Takeownlog -append -encoding Default
        Write-Output "" | Out-File $Takeownlog -append -encoding Default
        #
        Write-Output "" | Out-File $Icaclslog -append -encoding Default
        Write-Output "Fixing inheritance: $ProfilePath\$SubFolder\WIN7.V2" | Out-File $Icaclslog -append -encoding Default
        ICACLS $ProfilePath\$SubFolder\WIN7.V2 /inheritance:e /c /t | Out-File $Icaclslog -append -encoding Default
    }
        # Deletes any old profiles winxp or win7.v2_*
        Write-Host "Removing any old profiles..."
        if(Test-Path -path $winxp){
        #if((-not(Test-Path -Path $winxp)) -and (-not(Test-Path -Path $winos)) -and (-not(Test-Path -Path $winvar)) {
        write-host "No old profiles to delete for $SubFolder"
        } Else
    {
    # If any old profiles are found it will delete them
    Write-Host "Old profiles found for $subfolder. Deleting now..."
    Remove-Item  -Path $winxp 

}
}


Write-Host ""
$EndDate = date
Write-Host "Started: $StartDate"
Write-Host "Ended:   $EndDate"
Write-Host ""

Первая часть скрипта для сброса наследования работает нормально, как показано ниже:

Fixing ownership and inheritance: D:\Work\Profiles\mcbridt 
Fixing ownership and inheritance: D:\Work\Profiles\singhj 
Fixing ownership and inheritance: D:\Work\Profiles\test1 
test2\WIN7.V2 does not exist. Moving on...

Started: 04/13/2015 16:25:09 
Ended:   04/13/2015 16:25:09

Но вторая часть для удаления любых "старых" профилей не работает вообще. Я перепробовал много итераций remove-item, но пока не могу понять это. Я ценю любые предложения и исправления.

Большое спасибо

3 ответа

Решение

Большое спасибо двум вышеупомянутым пользователям, которые смогли направить меня в правильном направлении. После небольшого изменения я смог заставить его работать. Это не красиво, но это работает.

cls
# Date and time script is started
$StartDate = date

# Date variable for 30 day buffer
$date = (Get-Date).AddDays(-30)

# Sets path and log variables
$ProfilePath = "<local drive>\<share>"
$LogPath = "C:\temp"
$Takeownlog = "$LogPath\Takeown.log"
$Icaclslog = "$LogPath\icacls.log"
$NoWIN7FolderLog = "$LogPath\NoWin7Folder.log"

# Deletes any previous log entries
del $Takeownlog -ErrorAction SilentlyContinue
del $Icaclslog -ErrorAction SilentlyContinue
del $NoWIN7FolderLog -ErrorAction SilentlyContinue

# Gets Subfolder list
$FolderList = Get-ChildItem $ProfilePath

# Main body of script. 
foreach ($SubFolder in $FolderList)
{
# Sets commonly known 'old' profile folder names
$winxpold = "$ProfilePath\$SubFolder\winx*"
$winosold = "$ProfilePath\$subfolder\%win*"
$win7old = "$ProfilePath\$subfolder\WIN7.V2.*"
$win7old2 = "$ProfilePath\$SubFolder\WIN7.V2_*"

   # Checks if the WIN7.V2 folder exists. If it doesn't, it logs it and moves to next folder
    if(-not(Test-Path -path $ProfilePath\$SubFolder\WIN7.V2)){
        Write-Host "No WIN7.V2 folders exists for: $subfolder" -ForegroundColor Red
        Write-Output "No WIN7.V2 folders exists for: $subfolder" | Out-File $NoWIN7FolderLog -Append -encoding default
        } Else
    {
    # If the WIN7.V2 folder does exist it will recursively set Ownership to Administrators and then set the inheritance on the WIN7.V2 folder
        Write-Host "Fixing ownership and inheritance for: $SubFolder" -foregroundcolor Green
        Write-Host "Path: $ProfilePath\$SubFolder" -ForegroundColor Green
        Write-Output "Fixing ownership and ineritance for: $ProfilePath\$SubFolder\WIN7.V2" | Out-File $Takeownlog -append -encoding Default
        takeown /f $ProfilePath\$SubFolder\WIN7.V2 /A /R /D Y | Out-File $Takeownlog -append -encoding Default
        Write-Output "" | Out-File $Takeownlog -append -encoding Default
        #
        Write-Output "" | Out-File $Icaclslog -append -encoding Default
        Write-Output "Fixing inheritance: $ProfilePath\$SubFolder\WIN7.V2" | Out-File $Icaclslog -append -encoding Default
        ICACLS $ProfilePath\$SubFolder\WIN7.V2 /inheritance:e /c /t | Out-File $Icaclslog -append -encoding Default
    }
        # Deletes any old profiles winxp or win7.v2_*
        if((Test-Path -path $winxpold) -or 
            (Test-path -Path $winosold) -or
            (Test-path -Path $Win7old) -or
            (Test-Path -path $win7old2)){
        Write-Host "Old profiles found for: $subfolder. Deleting now..." -ForegroundColor Yellow 
        Write-Output "Old profiles found for: $subfolder. Deleting now..." | Out-File $Icaclslog -append -encoding Default
        Get-ChildItem -Path $ProfilePath\$subfolder -Force | 
        Where-Object { $_.PSIsContainer -and $_.LastWriteTime -lt $date -and $_.Name -like "winx*" -or $_.Name -like "%win*" -or $_.Name -like "WIN7.V2.*" -or $_.Name -like "WIN7.V2_*" } | 
        Remove-Item -Recurse -Force
        } Else{
        write-host "No old profiles to delete for: $SubFolder" -ForegroundColor Green}
        Write-Host ""

}
Write-Host ""
$EndDate = date
Write-Host "Started: $StartDate"
Write-Host "Ended:   $EndDate"
Write-Host ""
        $limit = (Get-Date).AddDays(-10)
        $path = "$ProfilePath\$subfolder\winxp"

        # Delete files older than the $limit.
    if(Test-Path -path $winxp){
        Write-Host "Old profiles found for $subfolder. Deleting now..."
    Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
        } Else{
write-host "No old profiles to delete for $SubFolder"}

в моем сценарии используйте -force для удаления файла, доступного только для чтения и скрытого файла, плюс вы можете использовать -whatif в конце сценария, чтобы узнать, что произойдет, если сценарий будет запущен

Команда удаления будет работать лучше, если вы используете Remove-Item -Path $winxp -recurse

Кроме того, и, что более важно, похоже, что ваша логика задом наперед в тестовой части XP.

if(Test-Path -path $winxp){
    write-host "No old profiles to delete for $SubFolder"
    } Else{
Write-Host "Old profiles found for $subfolder. Deleting now..."
Remove-Item  -Path $winxp}

наверное должно быть...

if(Test-Path -path $winxp){
Write-Host "Old profiles found for $subfolder. Deleting now..."
Remove-Item  -Path $winxp -Recurse
}Else{
write-host "No old profiles to delete for $SubFolder"}

Кроме того, похоже, что сценарий должен попасть в этот раздел, если он попадает в части до и после, как это происходит в примере вывода.

Другие вопросы по тегам