How to pass a parameter from the URL to a SharePoint Form (2025)

For a few months, there is a new way to display a new form for a SharePoint List, using Microsoft Forms:

This kind of form can be useful for intake requests or surveys. But how to pass a parameter in the URL to apply it to a field in the form?

Here is the solution I deployed:

  1. Create a Power Automate Flow that will replace the default value of the field with a defined value
  2. Create a Power App to intercept the parameter from the URL, to trigger the above flow, and to redirect the user to the form
  3. The user will see the defined value in the field because we use the default value
  4. A few seconds later, the flow will change back the default value to blank

It works well. The only downside is that we cannot have more than 1 person clicking on the link at the same time (and within a range of 15 seconds).

1) The Power Automate Flow

The flow is called by a Power App with a string parameter.

Then we do an HTTP call to SharePoint with the below details:

  • Method: PATCH
  • Uri: _api/web/lists/GetByTitle(‘SHAREPOINT LIST NAME’)/Fields/GetByInternalNameOrTitle(‘FIELD_ID’)
  • Headers: “Accept: application/json;odata=nometadata”, “Content-Type: application/json;odata=nometadata”, and “IF-MATCH: *”
  • Body: we use a JSON {"DefaultValue": "VALUE PROVIDED BY APP"}

By default value, I mean this information (legacy SharePoint interface):

Once the default value of the field has been updated, we respond back to the Power App.

We add a 15-second delay.

And finally, we do another HTTP call to SharePoint, with the same info, except for the body that becomes {"DefaultValue":""} to reset the default value.

2) The Power App

Instead of giving the direct link to the form to the user, we’ll give them a link to the Power App. The URL must contains the param value (e.g. “&Title=Code_123456”).

The App can have a short text (e.g. “click the below button to get to the survey”) with a button “Go to the form”.

When the user clicks on the button, it will trigger the flow we created in step 1, and then it will redirect the user to the form.

To do so, for OnSelect on the button:

// we can change the aspect of the button to indicate something is happening
Set(buttonLabel, "Loading survey…");
Set(buttonMode, DisplayMode.Disabled);

// decode the "Title" param that is passed in the URL
Set(
  titleParam,
  Substitute(
    Substitute(
        Substitute(
        Substitute(
            Substitute(Param("Title"), "%3A", ":"),
            "%2F", "/"
        ),
        "%3F", "?"
        ),
        "%3D", "="
    ),
    "%26", "&"
    )
);

// call the Power Automate Flow
'PowerApps–SetURLParamasDefaultValue'.Run(titleParam);

// then redirect to the form
Launch(urlToForm, {}, LaunchTarget.Replace);

3) Let’s the magic happen

When the user clicks on the button:

  • the flow runs,
  • the flow changes the default value using the provided param,
  • the flow says to the app to proceed,
  • the app redirects the user to the form,
  • the form shows up with the field that already contains the provided value
  • 15 seconds later (the time for the form to load), the flow resets the default value

Mise à jour d’un serveur Kimsufi (OVH) depuis Debian 11 (Bullseye) vers Debian 12 (Bookworm)

Cette mise à jour est similaire à ce qui a pu être fait précédemment.

Je vais essayer d’expliquer brièvement les étapes à suivre.

  1. D’abord s’assurer de la version actuelle de Debian avec la commande suivante :
    lsb_release -a
  2. On vérifie les problèmes liés à la mise à jour.
  3. Il est recommandé d’utiliser le programme /usr/bin/script pour enregistrer une transcription de la session de mise à niveau. Ainsi, quand un problème survient, on a un enregistrement de ce qui s’est passé. Pour démarrer un enregistrement, taper :
    script -t 2>~/upgrade-debian.time -a ~/upgrade-debian.script
  4. On va effectuer une mise à jour des paquets avec apt-get update && apt-get upgrade
  5. On va sauvegarder les données :
    mkdir /root/svg_special; cp -R /var/lib/dpkg /root/svg_special/; cp /var/lib/apt/extended_states /root/svg_special/; dpkg --get-selections "*" > /root/svg_special/dpkg_get_selection; cp -R /etc /root/svg_special/etc
  6. Si vous utilisez MariaDB, il peut être bien de faire une sauvegarde complète des bases de données :
    mysqldump -u root -p --all-databases > /root/svg_special/backup-bdd.sql
  7. Ensuite il est conseillé d’utiliser screen pour pouvoir se reconnecter (avec screen -r) à en cas de déconnexion :
    screen
  8. Le processus de mise à niveau décrit sur le site de Debian a été conçu pour des mises à niveau des systèmes « purs » sans paquet provenant d’autres sources. Pour une meilleure fiabilité du processus de mise à niveau, vous pourriez vouloir supprimer ces paquets tiers du système avant de commencer la mise à niveau :
    aptitude search '~i(!~ODebian)'
  9. On peut éventuellement purger les vieux paquets obsolètes. Pour cela on va d’abord les lister, puis on peut les purger si tout semble bon:
    aptitude search '~o'
    aptitude purge '~o'
  10. On peut lancer la commande dpkg --audit pour s’assurer que tout est bon avant la migration. On peut également taper dpkg --get-selections "*" | more et vérifier qu’aucun paquet n’est en on hold
  11. Maintenant il faut remplacer tous les “bullseye” de /etc/apt/sources.list par des “bookworm”.
    On pourra par exemple utiliser la commande suivante :

    sed -i 's/bullseye/bookworm/g' /etc/apt/sources.list

    Si vous utilisez le dépôt “non-free” de Debian 11 (ouvrez le fichier /etc/apt/sources.list pour voir si vous avez des lignes qui contiennent le mot-clé “non-free”), alors il y a une modification supplémentaire à effectuer : il faut ajouter “non-free-firmware” à la suite du mot-clé “non-free”.
    Par exemple, la ligne deb http://security.debian.org/debian-security bookworm-security main contrib non-free deviendra deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
    On pourra par exemple utiliser la commande suivante :

    sed -i 's/non-free/non-free non-free-firmware/g' /etc/apt/sources.list

    On vérifiera aussi les fichiers qui se trouvent dans /etc/apt/sources.list.d afin d’y effectuer les mêmes modifications.

  12. On passe aux choses sérieuses, en commençant par mettre à jour les listes des paquets :
    apt-get update
  13. On va vérifier qu’on a la place suffisante (un message explicite apparait sinon) :
    apt -o APT::Get::Trivial-Only=true full-upgrade
  14. On va maintenant faire une mise à jour minimale :
    apt-get upgrade
  15. Et à partir de là le système va vous questionner… en général choisir l’option par défaut si vous ne savez pas quoi répondre
  16. Puis on continue avec
    apt full-upgrade

Cette dernière étape va durer un certain temps. Une fois terminé, vous pouvez redémarrer le serveur pour s’assurer que tout va bien.

PHP

Il est bien de vérifier que la version actuelle de PHP est correctement utilisée par Apache et qu’elle correspond à ce qu’on veut. Pour cela on vérifie la version avec:

php -v

Ensuite on regarde les versions de PHP disponibles dans les modules d’Apache :

ls -l /etc/apache2/mods-available/php*

Et on regarde celle activée :

ls -l /etc/apache2/mods-enabled/php*

On regarde également dans le dossier des modules pour vérifier quelle version on a :

ls -l /etc/apache2/modules/libphp*

Si la version souhaitée est manquante dans les modules, alors on l’installe, par exemple pour la 8.4 :

apt-get install php8.4 php8.4-mysql

On s’assure ensuite de bien activer la bonne version, par exemple en passant de la v7.4 à v8.4 :

a2dismod php7.4
a2enmod php8.4

Et on redémarre Apache :

systemctl restart apache2

MariaDB

Cela peut être l’occasion de mettre à jour MariaDB. Si vous aviez un fichier /etc/apt/sources.list.d/mariadb.list, vous pouvez le supprimer et le remplacer par le fichier mariadb.sources comme indiqué dans la documentation de MariaDB.

Puis, comme indiqué dans la doc :

apt-get update
apt-get install mariadb-server

Pour finir

Une fois les erreurs corrigées, on va nettoyer tous les paquets avec :

apt-get autoremove

Note : pour arrêter screen on fait CTRL + A puis k.

Quoi faire en Thaïlande (Bangkok, Chiang Mai et Koh Yao Yoi) ?

Voici un retour d’expérience suite à notre séjour en janvier 2025.

À savoir

  • La carte bancaire est peu acceptée là bas, il faudra donc prévoir du cash.
  • Prévoir des chaussures faciles à enlever/mettre car on doit se déchausser dans tous les temples !
  • Concernant les tenues dans les temples, il est en général accepté que les hommes soient en short et éventuellement débardeur (mais t-shirt recommandé), par contre les femmes devront avoir un pantalon et couvrir leurs épaules. La seule exception qu’on ait rencontré est le Grand Palais de Bangkok où les hommes doivent aussi porter un pantalon.
  • Pour les déplacements, l’application Grab (pour Android ou iOS) remplace Uber et vous permet de prendre facilement des VTC sans vous faire arnaquer ni devoir négocier.

Bangkok

  • Traversée du fleuve : des bateaux-bus assurent plusieurs arrêts le long de la rivière – vous pouvez par exemple prendre le bateau à Phra Arthit et vous arrêter au Sathorn Pier. Vous prenez les tickets directement sur place en indiquant votre destination – les trajets sont plutôt rapides (entre 15 et 45 minutes).
  • Le rooftop de la Tour MahaNakhon : allez-y au moment du coucher du soleil pour profiter d’une vue incroyable sur la ville. On y retrouve un sol en verre (il faut prendre des chaussons pour y aller et les photos sont interdites sur le sol en lui-même mais on peut vous prendre en photo depuis l’extérieur de la zone délimitée). Au rez de chaussée on y trouve aussi des restaurants et des animations en réalité virtuelle – prévoir une à deux heures de visite.
  • Les temples que nous avons aimés : le Grand Palais (mais énormément de monde donc prévoir une visite tôt le matin) et le Wat Arun (bien qu’il soit le temple du lever, pas de nécessiter de s’y rendre tôt le matin – il faut bien explorer les alentours pour ne pas louper les différentes dépendances), et le Wat Pho avec son bouddha allongé – prévoir une à deux heures par temple
  • Temples que nous n’avons pas pu faire : Wat Khuin Chan (on l’a vu depuis la rivière et ça avait l’air joli) et le Temple du Dragon (vu sur Internet)
  • Expédition à Ayutthaya : l’ancienne capitale n’est plus que ruines, mais on y découvre quelques temples sympas, dont celui avec la tête de bouddha (le Wat Mahathat). Nous avons utilisé GetYourGuide pour organiser une journée là bas avec un petit groupe et repas du midi – prévoir une journée de visite depuis Bangkok.

Chiang Mai

  • Le Silver Temple ne figure pas sur les guides, alors qu’il s’agit d’un des plus beaux temples ! Sûrement qu’il n’est pas mentionné car il est interdit aux femmes de pénétrer dans ce petit temple : elles pourront cependant entrer dans le sanctuaire et faire le tour du temple pour admirer les très nombreuses gravures – prévoir une trentaine de minutes sur place
  • Mae Kha Canal n’est pas non plus dans les guides : il s’agit d’une petit canal le long duquel plusieurs échoppes d’inspiration nippones se sont installées. La balade est à faire de nuit pour profiter des beaux éclairages et pour déguster quelques mets japonais – prévoir une heure, si vous y mangez
  • Le temple Wat Lok Moli, et le Wat Rajamontean qui se trouve juste en face, valent le détour ! Nous les avons trouvé différents des autres temples que l’on peut voir dans la région – prévoir une grosse demi-heure
  • Sur GetYourGuide on peut trouver des expéditions de quelques heures pour visiter le temple Wat Pha Lat (très beau car plongé au milieu de la nature) ainsi que le temple Wat Phrathat Doi Suthep (lieu hautement spirituelle avec son immense escalier et sa vue panoramique sur la région) ; notre pack comprenait un arrêt à la cascade de Huay Keaw : un lieu charmant mais pas exceptionnel – prévoir une grosse demi-journée pour l’expédition
  • Si vous cherchez un lieu plus authentique que le Night Bazaar, alors visitez le Warorot Market en journée : des tonnes de stands de nourriture et autres bricoles pour les locaux. Possibilité de grignoter quelques plats sur place – prévoir 45 minutes si vous trainez un peu
  • Pour les visites, il y a bien sûr les classiques comme Wat Phra Singh et Wat Chedi Luang qui sont à voir – prévoir 2 heures pour la visite des deux
  • Si vous n’êtes pas loin du temple Wat Chiang Man, arrêtez-y vous quelques minutes : il est paisible et agréable – prévoir moins de 30 minutes
  • Pour finir, vous avez quelques bars/restaurants au bord du fleuve qui sont agréables le soir, avec toutes leurs guirlandes, comme le River View Bar.

Baie de Phang Nga (Province de Phuket)

Nous avons séjourné dans le Santhiya Koh Yao Yai Resort : un hôtel absolument magique, mais que je ne recommanderais pas car l’île de Koh Yao Yai ne propose pas grand chose à voir… Si vous partez en mode “farniente” et que votre but est de traîner au bord de la piscine/mer toute la journée, alors vous y serez sûrement tranquilles, mais si vous souhaitez visiter les nombreuses îles de la baie, ou explorer les environs, ce n’est pas l’idéal.
Sans l’avoir faite, l’île jumelle (Koh Yao Noi) semble être plus animée.

L’unique journée sortie que nous avons faite est pour aller jusqu’à Hong Island (Ko Hong) qui possède un observatoire à 360 degrés. Un endroit sublime – de là notre bateau nous a déposé dans plusieurs plages/ilots où nous avons pu admirer des singes, chauves-souris, oiseaux, et poissons en tout genre.

AndroidManifest.xml from ADB

It’s possible to find the AndroidManifest.xml file for an app using its APK (e.g. from APKMirror) and then with the help of a tool like jadx, but we can also connect to the Android device using adb connect, and then we use adb shell dumpsys package PACKAGE_NAME (e.g. “com.netflix.ninja” is the package name for Netflix).

This command will return many information similar to what the AndroidManifest.xml can provide.

Power FX: Dynamically access an object property with a variable

I’m kind of new with Power Apps, and it’s been very difficult to find how to access an object property using a variable.

In a nutshell, here are to access it:

With(
  { tempData: ParseJSON(JSON(ThisItem, JSONFormat.IgnoreBinaryData & JSONFormat.IgnoreUnsupportedTypes)) },
  Concat(
    ForAll(
      ColumnArray As ColumnName,
      ColumnName.Value & "=>" & Column( tempData, ColumnName.Value ) & "<br>"
    ),
    Value
  )
)

I’m transforming my record ThisItem to an UntypedObject to make it work with Column(), using JSON and by removing the problematic properties (thanks to JSONFormat.IgnoreBinaryData & JSONFormat.IgnoreUnsupportedTypes).

Then I iterate my array (a.k.a ColumnArray) that contains the property I need, and I use Column( tempData, ColumnName.Value ) to extract the column from the record!

My use case: I defined a collection with a list of columns, then I have a Gallery in which I have an HTMLText component that must display the columns from ThisItem based on the collection I defined before.

So, in App screen, I defined my collection like that:

ClearCollect(ColumnArray,["ID", "Title", "Description", "Target_x0020_Start_x0020_Date", "AssignedTo"]);
ClearCollect(UserColumns, ["AssignedTo"]);

Then in my Gallery, I have an HTMLText object with the below content:

"<div style='display:grid;grid-template-columns: 100px 50px 1fr 1fr 100px 150px;gap: 0px;height:65px;max-height:65px;overflo:hidden'><div style='"&cssTdStyle&";display:flex;justify-content:center;'><button type='button'>Edit</button></div>" &
With(
  { tempData: ParseJSON(JSON(ThisItem, JSONFormat.IgnoreBinaryData & JSONFormat.IgnoreUnsupportedTypes)) },
  Concat(
    ForAll(
      ColumnArray As ColumnName,
      "<div style='"&cssTdStyle&"'>" &
  If(
    ColumnName.Value in UserColumns,
    Column( tempData, ColumnName.Value ).DisplayName,
    Column( tempData, ColumnName.Value )
  )
  & "</div>"
    ),
    Value
  )
)
& "</div>"

This way I can make my display dynamic, based on a list of columns (that can be populated using a Power Automate Flow). I’ll have to identify which columns are User type, or similar ones, in order to access to the next property (like .DisplayName).

Quoi faire à Singapour ?

Voici quelques recommandations de visites à Singapour :

  • Clarke Quay : placé au bord d’un canal, vous y trouverez plein de restaurants et bars, une sorte de food court avec de petits bâtiments colorés et qui est très animé, surtout le soir. Depuis ce port, il est possible de prendre un bateau qui vous emmènera sur une petite croisière jusqu’au Marina Bay Sands – il est recommandé de faire cette croisière en début de soirée afin de pouvoir assister au spectacle des fontaines (voir horaires sur le lien) de l’hôtel emblématique de Singapour. – prévoir environ 2 heures sur place (selon si vous mangez ou si vous faites la croisière)
  • Symbole de la ville, le Merlion est une grande fontaine représentant une créature mi-lion mi-sirène. Par ailleurs vous aurez un beau point de vue sur l’hôtel-bâteau Marina Bay Sands. – prévoir environ 15 minutes sur place (il peut être intéressant de marcher depuis Clarke Quay jusqu’à Merlion puis de continuer jusqu’à l’intérieur du Marina Bay Sands)
  • L’emblématique Gardens by the Bay, avec ses super-arbres, est un lieu à ne pas manquer. Vous pouvez vous promener gratuitement dans les grands jardins et aux pieds des super-arbres, par contre il faudra acheter des tickets (en vente également sur place) pour visiter le Flower Dome (un grand dôme dans lequel on trouve beaucoup d’espèces de plantes – pas très intéressant) et le Cloud Forest (un grand dôme avec une forêt équatoriale et des passerelles en hauteur – très sympa à faire), ainsi que pour monter en haut des super-arbres. – prévoir environ 3h sur place
  • À ne pas louper, il y a le Buddha Tooth Relic Temple qui est un très beau temple bouddhiste, qui s’illumine la nuit. L’entrée est gratuite pour le visiter. De là vous avez le Maxwell Food Centre avec un grand choix de nourriture locale, ainsi que le très coloré temple hindou Sri Mariamman Temple. Bien sûr, Chinatown s’étend tout autour avec de quoi faire quelques emplettes ! – les temples se visitent en une quinzaine de minutes, pour le reste, tout dépend à quel point vous souhaitez flâner
  • Si vous avez du temps, allez voir le peu connu Science Center Singapore qui regorge de très nombreuses expériences scientifiques et ludiques qui raviront petits et grands (palais des miroir, jeux vidéos, illusions d’optique, le Fire Tornado, etc.). – prévoir au moins 3 heures, selon si vous êtes curieux, avez des enfants, et comprenez bien l’anglais
  • Avant de repartir, pensez à arriver très tôt à l’aéroport afin de pouvoir profiter de l’incroyable centre commercial Jewel Changi qui jouxte les terminaux, avec son dôme, sa forêt tropical et sa chute d’eau complètement dingue ! Des boutiques par dizaines et même le dernier étage avec ses activités (payantes) pour occuper vos dernières heures. C’est clairement à voir pour vivre un moment inoubliable face à ces milliers de litres d’eau qui tombent du ciel, tandis que le monorail traverse le dôme… – prévoir au moins 1 heure pour admirer les beautés du lieu et explorer les différentes boutiques

Recevoir des alertes lors de la diffusion d’un programme

Trop souvent je loupe des émissions TV que j’aime bien (comme “Qui veut être mon associé ?”, “Rendez-vous en terre inconnue”, …). J’ai cherché un service sur le Net qui me permettrait de recevoir un email lorsque mon émission préférée était diffusée, mais je n’ai rien trouvé.

J’ai donc créé https://alerte-tv.kodono.info/ qui permet d’être tenu au courant lorsqu’un programme est diffusé à la télévision française.

Utiliser un VPN sur l’iPad via un serveur Debian

Je vais expliquer ici comment installer un serveur VPN WireGuard sur Debian et l’utiliser depuis un iPad.

1. Serveur Debian

Sur le serveur, on installe WireGuard avec apt install wireguard -y.

2. Générer la clé privée et publique du serveur

Pour cela, on va faire :

sudo wg genkey | sudo tee /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_private.key | sudo wg pubkey | sudo tee /etc/wireguard/server_public.key

On retrouvera nos clés dans les fichiers /etc/wireguard/server_private.key et /etc/wireguard/server_public.key

3. Générer la clé privée et publique du client

Sur le serveur Debian, on va générer des clés pour le client :

wg genkey | tee client_private.key
cat client_private.key | wg pubkey | tee client_public.key

On retrouvera nos clés dans les fichiers ./client_private.key et ./client_public.key

4. Configuration du serveur

On va entrer la configuration suivante dans le fichier /etc/wireguard/wg0.conf :

[Interface]
Address = 10.0.0.1/24
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = PRIVATE_KEY_DU_SERVEUR

[Peer]
PublicKey = PUBLIC_KEY_DU_CLIENT
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25

5. Activer le transfert IP sur le serveur

Éditer le fichier /etc/sysctl.conf afin d’avoir :

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Et on applique les changements avec la commande sudo sysctl -p

6. Démarrage de WireGuard

Pour démarrer le serveur VPN on tape sudo systemctl start wg-quick@wg0

On peut voir le statut avec la commande sudo systemctl status wg-quick@wg0

7. Configuration du client

Sur notre client (ici un iPad), on installe l’application WireGuard depuis le App Store.

Ensuite, sur notre serveur, on va créer le fichier de configuration client.conf qui sera utilisé par le client, avec le contenu suivant :

[Interface]
PrivateKey = PRIVATE_KEY_DU_CLIENT
Address = 10.0.0.2/32
DNS = 8.8.8.8, 8.8.4.4 # on utilise les DNS de Google

[Peer]
PublicKey = PUBLIC_KEY_DU_SERVEUR
Endpoint = mon_serveur.debian.home:51820 # on indique l'IP/hostname de notre serveur VPN
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

Afin de transmettre cette configuration à l’iPad, on peut générer un QR code. Pour cela on installe ce qu’il faut : sudo apt install qrencode, puis on génère avec qrencode -t ansiutf8 < client.conf

Sur l'iPad, on ouvre l'application WireGuard puis on ajoute un client en utilisant le QR Code généré.

8. Vérification

En activant le VPN sur l'iPad, on peut tester si tout fonctionne comme prévu en vérifiant l'adresse IP de l'iPad.
Sur le serveur, on peut utiliser la commande wg show pour voir un peu ce qu'il se passe.

Remove lazy loading for a custom SPFx webpart

SharePoint Online is doing lazy loading when we hit a page with webparts. If you created a SPFx webpart, and if it’s not visible right after the page load, then it will only be loaded once the user scrolls to it…

To remove this behavior, and load the webpart as soon as possible, you must declare your webpart as a dynamic data source.

Here is the minimal code example (in pure JS, not in TS):

import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { DisplayMode } from '@microsoft/sp-core-library';

export default class HtmlViewerWebPart extends BaseClientSideWebPart {
  constructor() {
    super();
    // the below is used by the dynamic data source to avoid lazy loading
    this._sourceId = 'my_webpart';
  }

  onInit() {
    // to avoid lazy loading of the webpart, we register it as a dynamic data source
    // we only need to do it during the Edit of the page
    if (this.isPageInEditMode() && this.context.dynamicDataSourceManager) {
      this.context.dynamicDataSourceManager.initializeSource(this);
      console.log('Dynamic Data Source initialized to avoid lazy loading.');
    }
    
    return Promise.resolve();
  }

  isPageInEditMode() {
    return this.displayMode === DisplayMode.Edit;
  }

  // we need to declare this method because it's used by the data source to avoid lazy loading
  getPropertyDefinitions() {
    return []
  }

  // we need to declare this method because it's used by the data source to avoid lazy loading
  getPropertyValue(propertyId) {
    return propertyId;
  }
}

Then, edit the page, which will trigger the dynamic data source registration, and publish it.