# FTP script broke on upgrade to Windows Server 2019

**URL:** <https://forum.inductiveautomation.com/t/ftp-script-broke-on-upgrade-to-windows-server-2019/67871>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [December 21, 2022, 12:43pm UTC](https://forum.inductiveautomation.com/t/ftp-script-broke-on-upgrade-to-windows-server-2019/67871 "2022-12-21T12:43:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [December 21, 2022, 12:43pm UTC](https://forum.inductiveautomation.com/t/ftp-script-broke-on-upgrade-to-windows-server-2019/67871/1 "2022-12-21T12:43:25Z")

</div>

Here's the bones of the script that worked on Windows Server 2012.

```auto
	logger = system.util.getLogger("ftp_param_report")
	import io
	import csv
	from ftplib import FTP
	
	machine = int(machine) # '03' -> 3, etc., from viewBanner radio group.
	logger.info('machine: 5 step 1')
	
	try:
		ftp.close() # This helped during debug if previous attempt didn't clean up.
	except:
		pass
	ftp = FTP()
	ftp.connect(10.11.12.13, 21)
	ftp.login('ftpuser', 'mySecret') # Login.
	ftp.set_pasv(False) # Required by the C-More panel for some reason.
	ftp.cwd('/Built-in_Flash/Recipe') # Change Working Directory
	logger.info('machine: 5 step 2')
		
	# Read the data from the PRODUCT_SKU file.
	with io.BytesIO() as binary_buffer: # io avoids having to download a file to disk with associated cleanup.
		try:
			# read all of products.csv into a binary buffer
			logger.info('machine: 5 step 3')
			ftp.retrbinary("RETR myFile.csv", binary_buffer.write) # Read the SKU file.
			logger.info('machine: 5 step 4')

```

On upgrade to Windows Server 2019 it never gets to step 4.

Running Windows CMD FTP client on the gateway I can see there's a problem.

```auto
ftp> ls
200 Port command successful.

```

But then it hangs there until it times out in 900 s. The directory listing is never returned.  
I think the problem is due to Windows not sticking to ports 20 and 21 (which are open for outbound) for the FTP connection and using a high port number which is blocked by Windows Firewall.

![Filezilla gateway](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/2/f2565629dd7f357dcfd4e755bc05601b89098fd7.png)  
_The problem can be replicated using Filezilla._

By the way, does anyone know what the `225, 217` means in the PORT command?

Has anyone got any suggestions?

---

<div class="post-metadata">

**Author:** ![kcollins](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kcollins/32/19646_2.png) [@kcollins](https://forum.inductiveautomation.com/u/kcollins)\
**Post date:** [December 21, 2022, 2:53pm UTC](https://forum.inductiveautomation.com/t/ftp-script-broke-on-upgrade-to-windows-server-2019/67871/2 "2022-12-21T14:53:53Z")

</div>

The `PORT` command for FTP (in _active_ mode) is what defines the port that the server will connect _back_ to the client with for the data channel. In your Filezilla example, it is two bytes that represent the port number:

 ![2022-12-21 at 8.51 AM](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/8/88846c44957dda0bfaf73fa65d484e0b8f128c60.png)

So you'd have to have port `57817` open through to the Windows Server 2019 machine in order to have that connection established. Unfortunately, that port is typically dynamically chosen from a wide range.

I'm not sure off the top of my head how to prescribe a more constrained dynamic port range for the client to suggest in `ftplib`...

EDIT: I had the active vs passive backwards in my initial post.. -\> ☕

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [December 21, 2022, 3:07pm UTC](https://forum.inductiveautomation.com/t/ftp-script-broke-on-upgrade-to-windows-server-2019/67871/4 "2022-12-21T15:07:22Z")

</div>

Thanks, Kevin. Active doesn't seem to fix it.

![Filezilla ACTIVE](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/4/04613868e46d33a36b94fa3aea8709f620375e29.png)

![Filezilla gateway 2](https://us1.discourse-cdn.com/inductiveautomation/original/3X/3/8/3874e7148889cd6be7f6acb1cbed4ecbc1133ef0.png)

This isn't an Ignition problem anymore. I might ask on StackOverflow.

---

<div class="post-metadata">

**Author:** ![kcollins](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kcollins/32/19646_2.png) [@kcollins](https://forum.inductiveautomation.com/u/kcollins)\
**Post date:** [December 21, 2022, 3:12pm UTC](https://forum.inductiveautomation.com/t/ftp-script-broke-on-upgrade-to-windows-server-2019/67871/5 "2022-12-21T15:12:30Z")

</div>

Yeah, my apologies for a supplementary post that I actually deleted earlier--I had active vs passive backwards in my head. Passive mode actually requests the server to send back an additional port for the client to connect to for the data channel (meaning you wouldn't have to make special firewall exceptions on your Windows Server 2019 side). I see that the `PASV` (default) actually was rejected by your target, so you were actually in _Active_ mode (same as Ignition) in Filezilla.

So at this point options look like:

- Open up a wider port range in Windows Firewall (perhaps from that specific host?) for the data channel dynamic port that will be opened by active mode ftp.
- Find a way to constrict that port range for active mode ftp in python2 `ftplib` (which I also wasn't having good luck finding) and then following through with the respective fw rule.
- Use an alternate means for file transfer? 🤷
