2016-11-24

Powershell 建立、修改 FTP 帳號設定及容量限制

IIS 的 FTP 某種程度上比 FileZilla 好用
因為帳號是由作業系統管理, 可以用 PowerShell 進行各種自動管理
以下為帳號管理的程式, 用來建立、修改帳號
包括: 帳號名稱、帳號說明、事件通知對象、容量限制等
預設給予權限為 Modify , 如果有需要設定 Read Only 或 Write Only 等權限
則直接在資料夾的 ACL List 上面編輯 NTFS Permission 就可以了
故不將這種設定寫成複雜的 PowerShell Script, 沒必要

另外還有一個找出即將到期帳號的 Script, 目前寫到一半
只能撈出來, 還沒寫 E-mail 的部份

CreateFTPAccount.ps1
===== 程式開始 =====
$FTPUsersGroupName = 'FTP_Users'
$UserEmailDomain = 'Contoso.com'

cls
Write-Host ""
Write-Host ""
Write-Host "`t---------- Create FTP User Account ----------"
Write-Host ""

$AccountName = (Read-Host "`tInput AccountName")

# Check AccountName Characters
if ([string]::IsNullOrEmpty($AccountName)) {
Write-Host ""
Write-Host "`tExist."
Write-Host ""
exit;
} else {
$AccountNameLegalCharacters = ([char[]]([char]48..[char]57)) + ([char[]]([char]65..[char]90)) + ([char[]]([char]97..[char]122))
$AccountNameCheck = $AccountName
$AccountNameLegalCharacters | foreach {$AccountNameCheck = $AccountNameCheck -Replace $_, ''}
if ($AccountNameCheck -ne '') {
Write-Host ""
Write-Host "`tAccountName Contains Illegal Character(s): $AccountNameCheck"
Write-Host ""
exit;
};
};

# Process User Account

Write-Host ""
Write-Host "`t`t--- Checking if Account [$AccountName] Already Exist..."
Write-Host ""

$UserExist = [ADSI]::Exists("WinNT://$Env:Computername/$AccountName")

if ($UserExist -eq $True) {
write-host "`t`tAccount [$AccountName] Exist, Checking Description Format..."
Write-Host ""
$User = [ADSI]"WinNT://$Env:Computername/$AccountName,user"
$Password = '(No Change)'

$DefaultExpireDateYear = ($User.AccountExpirationDate).Year
$DefaultExpireDateMonth = ($User.AccountExpirationDate).Month
$DefaultExpireDateDay = ($User.AccountExpirationDate).Day

$DefaultUserDescriptionArray = $User.Description -Split "#"
if ($DefaultUserDescriptionArray.Count -ne 3) {
write-host "`t`tAccount [$AccountName] Description Format is Incorrecy, Please Modify Manually."
Write-Host ""
exit;
} else {
write-host "`t`tAccount [$AccountName] Description Format is OK, Enter Modify Mode."
Write-Host ""
if ([string]::IsNullOrEmpty($QuotaNotifyUser)) {
$DefaultQuotaNotifyUser = $DefaultUserDescriptionArray[0]
$DefaultQuotaNotifyUserDisplay = "(Default: $DefaultQuotaNotifyUser)"
};
$DefaultQuota = $DefaultUserDescriptionArray[1]
$DefaultQuotaDisplay = ' [Default: ' + $DefaultQuota+ ' (GB)]'
$DefaultAccountDesc = $DefaultUserDescriptionArray[2]
$DefaultAccountDescDisplay = "(Default: $DefaultAccountDesc)"
};
} else {
write-host "`t`tAccount [$AccountName] Not Exist, Enter Create Mode."
Write-Host ""
$DefaultQuotaDisplay = ' [Default: 1 (GB)]'
$DefaultExpireDateYear = ((Get-Date).AddDays(7)).Year
$DefaultExpireDateMonth = ((Get-Date).AddDays(7)).Month
$DefaultExpireDateDay = ((Get-Date).AddDays(7)).Day
};
$DefaultExpireDate = '' + $DefaultExpireDateYear + '.' + $DefaultExpireDateMonth + '.' + $DefaultExpireDateDay


$AccountDesc = (Read-Host "`tInput Account Desciption $DefaultAccountDescDisplay")
if ([string]::IsNullOrEmpty($AccountDesc)) {
if (([string]::IsNullOrEmpty($DefaultAccountDesc)) -eq $False) {
$AccountDesc = $DefaultAccountDesc
};
} else {
if (([string]::IsNullOrEmpty($DefaultAccountDesc)) -eq $False) {
$AccountDesc = $DefaultAccountDesc + ' , ' + $AccountDesc
};
};
write-host "`t  -- Account Desciption: $AccountDesc"
Write-Host ""

$DiskQuota = (Read-Host "`tInput Disk Quota $DefaultQuotaDisplay")

# Check Quota Characters
if ([string]::IsNullOrEmpty($DiskQuota)) {
if ([string]::IsNullOrEmpty($DefaultQuota)) {
$DiskQuota = '1'
} else {
$DiskQuota = $DefaultQuota
};
} else {
$DiskQuotaLegalCharacters = ([char[]]([char]48..[char]57))
$DiskQuotaCheck = $DiskQuota
$DiskQuotaLegalCharacters | foreach {$DiskQuotaCheck = $DiskQuotaCheck -Replace $_, ''}
if ($DiskQuotaCheck -ne '') {
Write-Host ""
Write-Host "`tDiskQuota Contains Illegal Character(s): $DiskQuotaCheck"
Write-Host ""
exit;
};
};
$DiskQuotaDesc = $DiskQuota
$DiskQuota = $DiskQuota + "GB"
write-host "`t  -- Disk Quota: $DiskQuota"
Write-Host ""

$QuotaNotifyUser = (Read-Host "`tInput Disk Quota Notify User $DefaultQuotaNotifyUserDisplay")

if ([string]::IsNullOrEmpty($QuotaNotifyUser)) {
if ([string]::IsNullOrEmpty($DefaultQuotaNotifyUser)) {
Write-Host ""
Write-Host "`t`tDisk Quota Notify User is Empty."
Write-Host ""
exit;
};
$QuotaNotifyUser = $DefaultQuotaNotifyUser
} else {
$QuotaNotifyUserLegalCharacters = ([char[]]([char]48..[char]57)) + ([char[]]([char]65..[char]90)) + ([char[]]([char]97..[char]122))
$QuotaNotifyUserCheck = $QuotaNotifyUser
$QuotaNotifyUserLegalCharacters | foreach {$QuotaNotifyUserCheck = $QuotaNotifyUserCheck -Replace $_, ''}
if ($QuotaNotifyUserCheck -ne '') {
Write-Host ""
Write-Host "`tDisk Quota Notify User Contains Illegal Character(s): $QuotaNotifyUserCheck"
Write-Host ""
exit;
};
};
write-host "`t  -- Disk Quota Notify User: $QuotaNotifyUser"
Write-Host ""

write-host "`tEnter Expire Date [Default: $DefaultExpireDate]"
$ExpireYear = (Read-Host "`tInput Expire Year")

# Check Year Characters
if ([string]::IsNullOrEmpty($ExpireYear)) {
$ExpireYear = $DefaultExpireDateYear
} else {
$YearLegalCharacters = ([char[]]([char]48..[char]57))
$YearCheck = $Year
$YearLegalCharacters | foreach {$YearCheck = $YearCheck -Replace $_, ''}
if ($YearCheck -ne '') {
Write-Host ""
Write-Host "`tYear Contains Illegal Character(s): $YearCheck"
Write-Host ""
exit;
};
};

$ExpireMonth = (Read-Host "`tInput Expire Month")

# Check Month Characters
if ([string]::IsNullOrEmpty($ExpireMonth)) {
$ExpireMonth = $DefaultExpireDateMonth
} else {
$MonthLegalCharacters = ([char[]]([char]48..[char]57))
$MonthCheck = $Month
$MonthLegalCharacters | foreach {$MonthCheck = $MonthCheck -Replace $_, ''}
if ($MonthCheck -ne '') {
Write-Host ""
Write-Host "`tMonth Contains Illegal Character(s): $MonthCheck"
Write-Host ""
exit;
};
};

$ExpireDay = (Read-Host "`tInput Expire Day")

# Check Day Characters
if ([string]::IsNullOrEmpty($ExpireDay)) {
$ExpireDay = $DefaultExpireDateDay
} else {
$DayLegalCharacters = ([char[]]([char]48..[char]57))
$DayCheck = $Day
$DayLegalCharacters | foreach {$DayCheck = $DayCheck -Replace $_, ''}
if ($DayCheck -ne '') {
Write-Host ""
Write-Host "`tDay Contains Illegal Character(s): $DayCheck"
Write-Host ""
exit;
};
};

$ExpireDate = "$ExpireYear.$ExpireMonth.$ExpireDay"
write-host "`t  -- Expire Date: $ExpireDate"
write-host ""

write-host "`t---------- Process ----------"
write-host ""
# Process User Account

if ($UserExist -eq $False) {

$PasswordNumber = (([char[]]([char]50..[char]57)) | sort {Get-Random})[0..2]
$PasswordCharacterLCase = (([char[]]([char]97..[char]107)) + ([char[]]([char]109..[char]110)) + ([char[]]([char]112..[char]122)) | sort {Get-Random})[0..2]
$PasswordCharacterUCase = (([char[]]([char]65..[char]72)) + ([char[]]([char]74..[char]78)) + ([char[]]([char]80..[char]90)) | sort {Get-Random})[0..2]
$Password = ($PasswordNumber + $PasswordCharacterLCase + $PasswordCharacterUCase | sort {Get-Random}) -join ''

$objOu = [ADSI]"WinNT://$Env:Computername"
$User = $objOU.Create("User", $AccountName)
$User.SetInfo()
$User = [ADSI]"WinNT://$Env:Computername/$AccountName,user"
$User.SetPassword($Password)
$User.SetInfo()
write-host "`tAccount [$AccountName] Created."
};

# Update Desc
if (([string]::IsNullOrEmpty($AccountDesc)) -eq $False) {
$UserDescription = "$QuotaNotifyUser#$DiskQuotaDesc#$AccountDesc"
$User.Description = $UserDescription
$User.SetInfo()
write-host "`tAccount [$AccountName] Description Updated"
} else {
$UserDescription = $User.Description
};

# Update ExpireDate
$ExpireDate = (Get-Date($ExpireDate))
$User.Put("AccountExpirationDate", $ExpireDate)
$User.SetInfo()
write-host "`tAccount [$AccountName] Expiration Date Updated"
write-host ""

# Check Group Members
$FTPUsersGroup = [ADSI]"WinNT://$Env:Computername/$FTPUsersGroupName,group"
$FTPUsersGroupMembers = $FTPUsersGroup.psbase.Invoke("Members")
$FTPUsersGroupMembers = $FTPUsersGroupMembers | ForEach-Object { $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) }
$AccountExist = 0
$FTPUsersGroupMembers | foreach {
if ($_ -eq $AccountName) {
$AccountExist = 1
};
};

if ($AccountExist -eq 0) {
write-host "`tAccount [$AccountName] Not in [$FTPUsersGroupName] Group. Adding it..."
$AddUserToGroup = $FTPUsersGroup.Add($User.Path)
write-host "`tAccount [$AccountName] Added to [$FTPUsersGroupName] Group."
write-host ""
};
#[ADSI]"WinNT://$Env:Computername/$AccountName,user" | select AccountExpirationDate

# Process Folder ACL
$FTP_Path = "D:\FTP_Files\LocalUser\$AccountName"

if ((Test-Path -Path $FTP_Path) -eq $false) {
$CreateFolder = New-Item $FTP_Path -type directory
write-host "`tAccount [$AccountName] Home Folder Created."
};

$colRights = [System.Security.AccessControl.FileSystemRights]"Modify"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow

$ACL = Get-ACL $FTP_Path
$ACLList = $ACL.Access | where {$_.IdentityReference -like "*$AccountName*"}
if ([string]::IsNullOrEmpty($ACLList)) {
$HF_ace = New-Object System.Security.AccessControl.FileSystemAccessRule($AccountName, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
$ACL.AddAccessRule($HF_ace)
Set-Acl -Path $FTP_Path -AclObject $ACL
write-host "`tAccount [$AccountName] Home Folder ACL Created."
} else {
if  (($ACLList.AccessControlType -eq "Allow") -and ($ACLList.FileSystemRights -eq "Modify, Synchronize")) {
write-host "`tAccount [$AccountName] Home Folder ACL Set"
} else {
write-host "`tAccount [$AccountName] Home Folder ACL is Not Standard, Please Modify Manually."
#$RemoveInCorrectACL = $ACL.RemoveAccessRule($ACLList)
#$HF_ace = New-Object System.Security.AccessControl.FileSystemAccessRule($AccountName, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
#$ACL.AddAccessRule($HF_ace)
#Set-Acl -Path $FTP_Path -AclObject $ACL
#write-host "`tAccount [$AccountName] Home Folder ACL Fixed."
};
};

write-host ""
# Set Quota
[uint64]$DiskQuota = "{0:N0}" -f ($DiskQuota / 1KB)
$DiskQuota = ($DiskQuota * 1KB)
$QuotaExisted = Get-FsrmQuota | where {$_.Path -eq $FTP_Path}
# Quota Existed
if (([string]::IsNullOrEmpty($QuotaExisted)) -eq $False) {
Remove-FsrmQuota -Path $FTP_Path -Confirm:$False
};

$QuotaMailSubject = '[Quota Threshold]% quota threshold exceeded'
$QuotaMailBody = 'The [Quota Threshold]% quota threshold for quota on [Quota Path] on server [Server] has been exceeded. The quota limit is [Quota Limit MB] MB and the current usage is [Quota Used MB] MB ([Quota Used Percent]% of limit).'
$CreateQuota = New-FsrmQuota -Path $FTP_Path -Description "FTP-$AccountName" -Size $DiskQuota
$ActionEmail = New-FsrmAction Email -MailTo "$QuotaNotifyUser@$UserEmailDomain" -Subject $QuotaMailSubject -Body $QuotaMailBody -RunLimitInterval 120
$ActionEmail_100 = New-FsrmAction Email -MailTo "[Admin Email];$QuotaNotifyUser@$UserEmailDomain" -Subject $QuotaMailSubject -Body $QuotaMailBody -RunLimitInterval 120
$ActionEvent = New-FsrmAction Event -EventType Information -Body "User [Source Io Owner] has exceeded the [Quota Threshold]% quota threshold for the quota on [Quota Path] on server [Server]. The quota limit is [Quota Limit MB] MB, and [Quota Used MB] MB currently is in use ([Quota Used Percent]% of limit)."
$Threshold_90 = New-FsrmQuotaThreshold -Percentage 90 -Action $ActionEvent, $ActionEmail
$Threshold_95 = New-FsrmQuotaThreshold -Percentage 95 -Action $ActionEvent, $ActionEmail
$Threshold_100 = New-FsrmQuotaThreshold -Percentage 100 -Action $ActionEvent, $ActionEmail_100
$Quota = Set-FsrmQuota -Path $FTP_Path -Threshold $Threshold_100, $Threshold_95, $Threshold_90
write-host "`tAccount [$AccountName] Home Folder Quota Set."

$DiskQuotaDisplay = ($DiskQuota / 1GB)

write-host ""
write-host "`t---------- Summary ----------"
write-host ""
write-host "`tAccountName: $AccountName"
write-host "`tPassword: $Password"
write-host "`tDiskQuota: $DiskQuotaDisplay GB"
write-host "`tExpireDate: $ExpireDate"
write-host "`tDescription: $UserDescription"
write-host "`tQuota Email: $QuotaNotifyUser@$UserEmailDomain"
write-host ""
write-host ""
===== 程式結束 =====


ExpirationNotify.ps1
===== 程式開始 =====

$FTPUsersGroupName = 'FTP_Users'

$FTPUsersGroup = [ADSI]"WinNT://$Env:Computername/$FTPUsersGroupName,group"
$FTPUsersGroupMembers = $FTPUsersGroup.psbase.Invoke("Members")
$FTPUsersGroupMembers = $FTPUsersGroupMembers | ForEach-Object { $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) }
$AccountExist = 0
$FTPUsersGroupMembers | foreach {
$User = [ADSI]"WinNT://$Env:Computername/$_,user"

$RemainDays = 0

if ((($User.AccountExpirationDate).GetType()).Name -eq 'PropertyValueCollection') {

# Get Notify User
$UserDescriptionArray = $User.Description -Split "#"
if ($UserDescriptionArray.Count -ne 3) {
break;
} else {
$QuotaNotifyUser = $UserDescriptionArray[0]
};

if ( ((($User.AccountExpirationDate).Date).AddDays(-7)).Date -eq ((Get-Date).Date) ) {
write-host "$QuotaNotifyUser, $_ Remains 7 Days to Expire " ($User.AccountExpirationDate).Date $UserExpireDateRemainSevenDays.Date
} elseif ( ((($User.AccountExpirationDate).Date).AddDays(-3)).Date -eq ((Get-Date).Date) ) {
write-host "$QuotaNotifyUser, $_ Remains 3 Days to Expire " ($User.AccountExpirationDate).Date $UserExpireDateRemainSevenDays.Date
};
};
};
===== 程式結束 =====

沒有留言: