Removing ip addresses in a list based on another

I have a set of lists I want to cleanup a specific IP from another address list.
It’s not working.. What am I doing wrong?

:local lists {"test1"; "test2"; "test3";};

:foreach ip in=[/ip firewall address-list find where list="CLEANUP"] do={
    :local ipAddresss [/ip firewall address-list get $ip address];
    :foreach list in=$lists do={
        /log info "$ipAddresss";
        /log info "$list";
        /ip firewall remove [/ip firewall address-list [find list=$list address=$ipAddress]]
    }
}

/log info "Ended Script";

There’s no “/ip firewall remove”. This works for me:

/ip firewall address-list remove [/ip firewall address-list find list="test" address="1.2.3.4"]

but only when I write list name and address like this, I can’t find a way how to make it work with variables. I assume it’s possible, somehow, but if I ever understand RouterOS scripting, it will be a miracle.

I asusme it’s lua scripting because many work with this but still…
I will try..

It’s not Lua, it’s MikroTik’s custom thing (they briefly had Lua in some beta version, but it didn’t make it to final). It wouldn’t be that bad, it’s slightly unintuitive, but it would be possible to get used to it. Main problem is that it doesn’t have any useful feedback, typo in code means silent death, without any indication what’s wrong. And then there’s things like this. I usually have no problem doing small things even in programming languages I don’t know, but not with RouterOS scripting, I get stuck all the time.

If I try simplified script:

:local list "test1";
:local ip "1.0.0.0";
:log info $list
:log info $ip
/log info [/ip firewall address-list find list="test1" address="1.0.0.0"];
/log info [/ip firewall address-list find list="test1" address=$ip];
/log info [/ip firewall address-list find list=$list address="1.0.0.0"];
/log info [/ip firewall address-list find list=$list address=$ip];

then I get:

18:04:43 script,info test1 
18:04:43 script,info 1.0.0.0 
18:04:43 script,info *5 
18:04:43 script,info *5 
18:04:43 script,info *5;*7;*8;*b 
18:04:43 script,info *5;*7;*8;*b

So variables have expected values and *5 is correct id for item I’m searching for. It means that second command with address=$ip works fine too. But next two find 1.0.0.0 in all address lists, so there’s some problem with list=$list. But what could it be?

Have a look at this commit, it explains the issue:
https://git.eworm.de/cgit/routeros-scripts/commit/?id=870f00bb36f5af3088344371764da48bbde9651a

Short conclusion: You are safe if your variable names are not lower case.

You’re right. It’s actually documented:

https://wiki.mikrotik.com/wiki/Manual:Scripting#Reserved_variable_names

So on one hand I can’t complain, but on the other it confirms what I’m saying, this whole thing is not intuitive (to me at least), because who would expect all property names to be reserved as variable names? :slight_smile:

Ah, did not know it is documented… Found it the hard way myself. :laughing:

OK Now I got it.
I will try it later and see how it goes.

I know this is a old thread, but
@elico can you fix your script mentioned on 1st post. I really need a script like this but i have zero knowledge of programming .

Thank you

Here is a script that I do use.
If an IP are found in access list “Whitelist_IP” and also fond in access list “Block_list”, remove it from “Block_list”
Then send a pushbullet message to my phone. (Can be any type of message, logging, email, telegram etc)


# Remove ip from block list if its white listed
# Jotne

# 1.1  get IP before used in loop to speed up seach. 29.05.2022
# 1.2  Added Pusbullet info 21.06.2022

/ip firewall address-list
:foreach id in=[find where list="Whitelist_IP"] do={
	:local IP [get $id address]
	:local Comment [get $id comment]
	:local IPFound [find where list="Block_list" address=$IP]
	:if ([:len $IPFound] > 0) do={
		remove $IPFound
		/tool fetch mode=https url="https://api.pushbullet.com/v2/pushes" http-method=post http-data="type=note&body=Unblock $IP $Comment" user="xxxxxxxxxxxxxx"
	}
}

thank you for your kindness. your script working well & you also gave me an idea to record removed IPs. I have replaced pushbullet with google sheet to record all removed ips to google spreadsheet.


not related to this thread, do you have a script to remove static IPs from the address list if it older than 30 days ( based on creation time).

This sript moves static IP that has more than 100 days of no use. You can see have I calculate days to get an idea on how to use it.

# Created Jotne 2021 v1.0
# Remove all static DHCP and corresponding DNS leases more than 100 week old
:local counter 0
/ip dhcp-server lease
:foreach id in=[find where dynamic=no last-seen~"^1[0-9][0-9]"] do={
	:local ip [get $id address]
	:set counter ($counter+1)
	# delete DNS entry with that IP
	/ip dns static remove [find where address=$ip]
	# remove DHCP entry
	remove $id
}
:log info message="script=dhcp_clean Number of static DHCP older>100weeks removed $counter"

You can not easily read the creation time “jul/19/2022 22:37:42” and compare with something.
Is a string, you can not compare if that string are 30 days less the current date.
Is extremely complicated (not impossible, ok) to do that.

Use timeout on item added on address-list and is auto purged after specified time.
If you do that, you do not use internal storage, the list is not exported on backup, and is not keeped on reboot.

Else, add Unix Epoch when is not present on static addres-list,
and check every day/hour if the numeric Epoch are 30 day (× 24h × 60m × 60s) less than current Epoch.

This has been discussed for many many years. I did hope with v7.x that MikroTik would use a standard time format.
For example EPOCH time.

Here are some help to do that.