I have got "how to create filezilla ftp account with powershell" problem.

Need help with FileZilla Server? Something does not work as expected? In this forum you may find an answer.

Moderator: Project members

Post Reply
Message
Author
aaronchen
500 Command not understood
Posts: 4
Joined: 2023-05-13 17:12
First name: aaron
Last name: chen

I have got "how to create filezilla ftp account with powershell" problem.

#1 Post by aaronchen » 2023-05-18 05:30

I tried to use the author's previous PowerShell syntax to rewrite and encountered problems. Can an expert guide me? Many thanks.
Filezilla Server 0.9.60 beta

#Script to create a new user in FileZilla
#Uses the Comments XML element under the User node for auditing
#
#Can be executed on a PC/server other than the FileZilla server (e.g. Remote Desktop server)
#
#Requirements:
#- A template FTP user account to be created on the FileZilla server (this makes it easy to set default option specific to your environment, e.g. Enforce SSL)
#- Additional Groups to be created manually in FileZilla Server, and to have the corresponding filesystem folders created manually too.
#- The user running this script needs Modify Share permissions on the $ftpDataShare share to create the directory for the new account
#- The user running this script needs NTFS Write permissions on the $ftpDataShare\$ftpGroup directories to create the directory for the new account
#- Editing the FileZilla XML:
# - The "%PROGRAM FILES (x86)%\FileZilla Server" directory on the FileZilla server to be shared as "FileZillaServer$" and the user running this script needs Change permissions on the share
# - The user running this script needs NTFS Modify permissions on the "\\$filezillaServer\FileZillaServer$\FileZilla Server.xml"
#- Reloading the FileZilla Config
# - Set-ExecutionPolicy to be set to RemoteSigned (or lower) on the computer running this script and on the FileZilla server (unless you sign the scripts yourself)
# - A script that contains the commands required to reload the FileZilla config (otherwise the FileZilla services need to be restarted)
# - A PSSessionConfiguration on the FileZilla server with a -RunAsCredential with local admin rights and Invoke permission (required for the /reload-config command to work)
# - This recommends a dedicated local administrator account on the FileZilla server that can be locked down further as required
#
#Does not require:
#- Local Administrator permissions for the user running this script on the computer running this script
#- Local Administrator permissions for the user running this script on the FileZilla server
#
#If you like the script, feel free to pop a beer in the post c/o Kev Maitland - I work at the head office of www.sustain.co.uk :)


$filezillaServer = "myserver.mydomain.dmz"
$ftpDataShare = "AaronTest"
$localPathToFTPDataShareOnFileZillaServer = "E:" #Used to map user's Home Folder locally, rather than via UNC
$xmlFilePath = "\\$filezillaServer\FileZillaServer$\FileZilla Server.xml"
$psSessionConfigurationNameOnFileZillaServer = "FileZilla"
$reloadFZConfigCmdPath = "\\$filezillaServer\FileZillaServer$\ReloadConfig.ps1"
$formTitle = "Secure FTP User Creation"
$disallowedCharacters = @("\<", "\>", "\:", '\"', "\/", "\\", "\|", "\?", '\*', "\ ", "\'", "\,", "\^") -join '|' #Use RegEx escape character (\) here, not PowerShell (`)
$date = Get-Date

function formCaptureText([string]$formTitle, [string]$formText){
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = $formTitle
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$script:capturedText = $objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close();$script:capturedText = ""}})


$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$script:capturedText=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close();$script:capturedText = ""})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,40)
$objLabel.Text = $formText
$objForm.Controls.Add($objLabel)

$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,60)
$objTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($objTextBox)

$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

$capturedText
}
function formCaptureSelection([string]$formTitle, [string]$formText, [string[]]$choices){
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = $formTitle
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$script:capturedSelection = $objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close();$script:capturedSelection = ""}})


$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$script:capturedSelection=$objListBox.SelectedItem;$objForm.Close()})
$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close();$script:capturedSelection = ""})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,20)
$objLabel.Text = $formText
$objForm.Controls.Add($objLabel)

$objListBox = New-Object System.Windows.Forms.ListBox
$objListBox.Location = New-Object System.Drawing.Size(10,40)
$objListBox.Size = New-Object System.Drawing.Size(260,20)
$objListBox.Height = 80
foreach ($choice in $choices){
[void] $objListBox.Items.Add($choice)
}
$objForm.Controls.Add($objListBox)

$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

$capturedSelection
}
function hashMeAPassword([string]$clearText){
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = new-object -TypeName System.Text.UTF8Encoding
$passHash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($clearText))).ToLower() -replace "-",""
$passHash
}

#Open the XML document so that we can check for duplicate usernames
$xml = [xml](Get-Content $xmlFilePath)

#Generate a form to capture the new account name and perform some validation. Usernames need to converted to lowercase as XML is case sensitive (and everything else is not)
$ftpUsernameValid = $false
$ftpUsername = (formCaptureText $formTitle "Please enter the new username below (don't use spaces or symbols in the username):").ToLower()
while ($ftpUsernameValid -eq $false){
if ($ftpUsername -eq ""){write-host "Empty username. Exiting now";exit} #If username is empty, quit.
$ftpUsernameValid = $true
if ($xml.SelectSingleNode("/FileZillaServer/Users/User[@Name='$ftpUsername']") -ne $null){ #Don't let the user choose an pre-existing username
$ftpUsernameValid = $false
$ftpUsername = (formCaptureText $formTitle "Username already in use - please choose another (don't use spaces or symbols):").ToLower()
}
if ($ftpUsername -match $disallowedCharacters){ #Make sure that the user hasn't chosen any spaces or symmbols in the account name
$ftpUsernameValid = $false
$ftpUsername = (formCaptureText $formTitle "Oi $env:username! I said /don't/ use spaces or symbols! Try again:").ToLower()
}
}

#Generate a form to capture the new password and perform some rudimentary validiation
$ftpPassword = formCaptureText $formTitle "Please enter the new (strong) password below:"
while (($ftpPassword.Length -lt 8) -or ($ftpPassword -eq $ftpUsername) -or ($ftpPassword -match "123")){
if ($ftpPassword -eq ""){write-host "Empty password. Exiting now";exit} #If password is empty, quit.
$ftpPassword = formCaptureText $formTitle "Don't be an idiot, $env:username. Enter a proper /strong/ password below."
}

#Generate a form to capture the new account's group (doesn't require additional validation as they are picking from a list)
$ftpGroupsArray = @()
foreach ($ftpGroup in $xml.FileZillaServer.Groups.Group){$ftpGroupsArray += $ftpGroup.Name} #Pull the list of Groups from the FileZilla XML
[Array]::Sort([array]$ftpGroupsArray) #Sort the list of Groups
$ftpGroupsArray += "None" #Add a final "None" option

$ftpGroup = formCaptureSelection "Secure FTP User Creation" "Please select the appropriate group for the new user:" $ftpGroupsArray
if ($ftpGroup -eq ""){write-host "Empty group. Exiting now";exit} #If either values are empty, quit.



cls
Write-Host -ForegroundColor Yellow "Creating new user: $ftpUsername / $ftpPassword / $ftpGroup"
#------------------------------------------
#---Create the folder structure
#------------------------------------------
Write-Host -ForegroundColor DarkYellow "Creating new folder at: \\$filezillaServer\$ftpDataShare\$ftpGroup\$ftpUsername"
if (!(Test-Path "\\$filezillaServer\$ftpDataShare\$ftpGroup\$ftpUsername")){
$null = New-Item -ItemType directory -Path "\\$filezillaServer\$ftpDataShare\$ftpGroup\$ftpUsername"
$null = New-Item -ItemType directory -Path "\\$filezillaServer\$ftpDataShare\$ftpGroup\$ftpUsername\$ftpUsername"
}
#------------------------------------------
#---Edit the FileZilla XML to add the new user
#------------------------------------------
Write-Host -ForegroundColor DarkYellow "Adding $ftpUsername to FileZilla"
$passHash = hashMeAPassword $ftpPassword

$newFZUser = ($xml.FileZillaServer.Users.User | ?{$_.Name -eq "TemplateFTPUser"}).clone() #Uses a template user called "TemplateFTPUser" that you've already created in FileZilla through the GUI
$newFZUser.Name = $ftpUsername
$newFZUser.SelectSingleNode("Option[@Name='Pass']").InnerText = $passHash
$newFZUser.SelectSingleNode("Option[@Name='Group']").InnerText = $ftpGroup
$newFZUser.SelectSingleNode("Option[@Name='Enabled']").InnerText = 1
$newFZUser.SelectSingleNode("Option[@Name='Comments']").InnerText = "Created by $env:username on $(get-date $date -Format "yyyy/MM/dd hh:mm:ss") updated by $env:username on $(get-date $date -Format "yyyy/MM/dd hh:mm:ss")"
$newfzuser.permissions.permission.dir = "$localPathToFTPDataShareOnFileZillaServer\$ftpDataShare\$ftpGroup\$ftpUsername"

$null = $xml.DocumentElement.Users.AppendChild($newFZUser)
$xml.Save($xmlFilePath)


#------------------------------------------
#---Reload the FileZilla config to initialise the new user
#------------------------------------------
Write-Host -ForegroundColor DarkYellow "Activating $ftpUsername ..."
Invoke-Command -ComputerName $filezillaServer -FilePath $reloadFZConfigCmdPath -ConfigurationName $psSessionConfigurationNameOnFileZillaServer


Write-Host -ForegroundColor Yellow "User setup complete! Press enter to exit this window"
$null = Read-Host


Result as below:
I modify PowerShell run on this server, and also using dmz admin account run it.

Creating new user: aarontest11 / P@ssword / AaronTest
Creating new folder at: \\myserver.mydomain.dmz\AaronTest\AaronTest\aarontest11
Adding aarontest11 to FileZilla
Activating aarontest11 ...

[myserver.mydomain.dmz] Connecting to remote server myserver.mydomain.dmz failed with the following error message : The
WS-Management service cannot process the request. Cannot find the FileZilla session configuration in the WSMan: drive on the
myserver.mydomain.dmz computer. For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (myserver.mydomain.dmz:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : InvalidResourceUri,PSSessionStateBroken
User setup complete! Press enter to exit this window

Result as below:
I modify PowerShell run on this server, and also using Internal domain admin account run it.

Creating new user: aarontest12 / P@ssword / AaronTest
Creating new folder at: \\myserver.mydomain.dmz\AaronTest\AaronTest\aarontest12
Adding aarontest12 to FileZilla
Activating aarontest12 ...

[myserver.mydomain.dmz] Connecting to remote server myserver.mydomain.dmz failed with the following error message : WinRM cannot
process the request. The following error occurred while using Kerberos authentication: Cannot find the computer myserver.mydomain.dmz.
Verify that the computer exists on the network and that the name provided is spelled correctly. For more information, see the
about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (myserver.mydomain.dmz:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : NetworkPathNotFound,PSSessionStateBroken
User setup complete! Press enter to exit this window

I also try to open WSman and WinRM see the about_Remote_Troubleshooting Help topic, I have no any idea? Please advice, Many thanks.

User avatar
botg
Site Admin
Posts: 35555
Joined: 2004-02-23 20:49
First name: Tim
Last name: Kosse

Re: I have got "how to create filezilla ftp account with powershell" problem.

#2 Post by botg » 2023-05-18 07:17

You need to update to the most recent version of FileZilla Server. Outdated versions are not supported.

aaronchen
500 Command not understood
Posts: 4
Joined: 2023-05-13 17:12
First name: aaron
Last name: chen

Re: I have got "how to create filezilla ftp account with powershell" problem.

#3 Post by aaronchen » 2023-05-19 02:58

I will try to upgrade other server for testing first, Could you know new create filezilla FTP user with powershell(new method), thanks.

Post Reply