See the question and my original answer on StackOverflow

Here's a sample C# Console Application using the official API IFolderView::SelectAndPositionItems method that can be used for that:

using System;
using System.Runtime.InteropServices;

namespace MyConsoleApp;

public class Program
{
    public static void Main()
    {
        // we basically follow https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933
        dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        var windows = app.Windows;

        const int SWC_DESKTOP = 8;
        const int SWFO_NEEDDISPATCH = 1;
        var hwnd = 0;
        var disp = windows.FindWindowSW(Type.Missing, Type.Missing, SWC_DESKTOP, ref hwnd, SWFO_NEEDDISPATCH);

        var sp = (IServiceProvider)disp;
        var SID_STopLevelBrowser = new Guid("4c96be40-915c-11cf-99d3-00aa004ae837");

        var browser = (IShellBrowser)sp.QueryService(SID_STopLevelBrowser, typeof(IShellBrowser).GUID);
        var view = (IFolderView)browser.QueryActiveShellView();
        var view2 = (IFolderView2)view;

        // get all items, dump & sets their position (here y+= 150)
        for (var i = 0; i < view.ItemCount(); i++)
        {
            // get some item's info to be able to determine if we want to move it or not
            var item = view2.GetItem(i, typeof(IShellItem).GUID);
            Console.WriteLine(item.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEPARSING));

            var pidl = view.Item(i);
            view.GetItemPosition(pidl, out var pt);
            Console.WriteLine("Current position: " + pt.x + ", " + pt.y);

            pt.y += 150;
            view.SelectAndPositionItems(1, new IntPtr[] { pidl }, new POINT[] { pt }, SVSIF.SVSI_POSITIONITEM);
            Console.WriteLine();
        }
    }

    [ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IServiceProvider
    {
        [return: MarshalAs(UnmanagedType.IUnknown)]
        object QueryService([MarshalAs(UnmanagedType.LPStruct)] Guid service, [MarshalAs(UnmanagedType.LPStruct)] Guid riid);
    }

    // note: for the following interfaces, not all methods are defined as we don't use them here
    [ComImport, Guid("000214E2-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IShellBrowser
    {
        void _VtblGap1_12(); // skip 12 methods https://stackoverflow.com/a/47567206/403671

        [return: MarshalAs(UnmanagedType.IUnknown)]
        object QueryActiveShellView();
    }

    [ComImport, Guid("cde725b0-ccc9-4519-917e-325d72fab4ce"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IFolderView
    {
        void _VtblGap1_3(); // skip 3 methods

        IntPtr Item(int iItemIndex);
        int ItemCount(uint uFlags = 0);

        void _VtblGap2_3(); // skip 2 methods

        void GetItemPosition(IntPtr pidl, out POINT ppt);

        void _VtblGap1_4(); // skip 4 methods

        void SelectAndPositionItems(int cidl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] apidl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] POINT[] apt, SVSIF dwFlags);

        // more undefined methods
    }

    [ComImport, Guid("1af3a467-214f-4298-908e-06b03e0b39f9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IFolderView2
    {
        void _VtblGap1_26(); // skip 14 (IFolderView) + 12 methods

        IShellItem GetItem(int iItemIndex, [MarshalAs(UnmanagedType.LPStruct)] Guid riid);

        // more undefined methods
    }

    [ComImport, Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IShellItem
    {
        [return: MarshalAs(UnmanagedType.IUnknown)]
        object BindToHandler(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid);

        IShellItem GetParent();

        [return: MarshalAs(UnmanagedType.LPWStr)]
        string GetDisplayName(SIGDN sigdnName);

        // more undefined methods
    }

    public struct POINT
    {
        public int x;
        public int y;
    }

    public enum SIGDN
    {
        SIGDN_NORMALDISPLAY,
        SIGDN_PARENTRELATIVEPARSING,
        SIGDN_DESKTOPABSOLUTEPARSING,
        SIGDN_PARENTRELATIVEEDITING,
        SIGDN_DESKTOPABSOLUTEEDITING,
        SIGDN_FILESYSPATH,
        SIGDN_URL,
        SIGDN_PARENTRELATIVEFORADDRESSBAR,
        SIGDN_PARENTRELATIVE,
        SIGDN_PARENTRELATIVEFORUI
    }

    [Flags]
    public enum SVSIF
    {
        SVSI_DESELECT = 0,
        SVSI_SELECT = 0x1,
        SVSI_EDIT = 0x3,
        SVSI_DESELECTOTHERS = 0x4,
        SVSI_ENSUREVISIBLE = 0x8,
        SVSI_FOCUSED = 0x10,
        SVSI_TRANSLATEPT = 0x20,
        SVSI_SELECTIONMARK = 0x40,
        SVSI_POSITIONITEM = 0x80,
        SVSI_CHECK = 0x100,
        SVSI_CHECK2 = 0x200,
        SVSI_KEYBOARDSELECT = 0x401,
        SVSI_NOTAKEFOCUS = 0x40000000
    }
}

PS: this code presumes the icon are not automatically arranged by the the shell configuration, otherwise it will have not effect.