diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json
index f6e0c39ab..600997dde 100644
--- a/src/dotnet/devcontainer-feature.json
+++ b/src/dotnet/devcontainer-feature.json
@@ -1,6 +1,6 @@
 {
     "id": "dotnet",
-    "version": "2.1.3",
+    "version": "2.2.0",
     "name": "Dotnet CLI",
     "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet",
     "description": "This Feature installs the latest .NET SDK, which includes the .NET CLI and the shared runtime. Options are provided to choose a different version or additional versions.",
diff --git a/src/dotnet/scripts/dotnet-helpers.sh b/src/dotnet/scripts/dotnet-helpers.sh
index 26e29fa36..84a674917 100644
--- a/src/dotnet/scripts/dotnet-helpers.sh
+++ b/src/dotnet/scripts/dotnet-helpers.sh
@@ -18,11 +18,11 @@ fetch_latest_version_in_channel() {
     local channel="$1"
     local runtime="$2"
     if [ "$runtime" = "dotnet" ]; then
-        wget -qO- "https://dotnetcli.azureedge.net/dotnet/Runtime/$channel/latest.version"
+        wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Runtime/$channel/latest.version"
     elif [ "$runtime" = "aspnetcore" ]; then
-        wget -qO- "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$channel/latest.version"
+        wget -qO- "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$channel/latest.version"
     else
-        wget -qO- "https://dotnetcli.azureedge.net/dotnet/Sdk/$channel/latest.version"
+        wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Sdk/$channel/latest.version"
     fi
 }
 
diff --git a/src/dotnet/scripts/vendor/dotnet-install.sh b/src/dotnet/scripts/vendor/dotnet-install.sh
index 38a160cf1..122ee68ed 100755
--- a/src/dotnet/scripts/vendor/dotnet-install.sh
+++ b/src/dotnet/scripts/vendor/dotnet-install.sh
@@ -423,11 +423,17 @@ get_normalized_architecture_for_specific_sdk_version() {
 # args:
 # version or channel - $1
 is_arm64_supported() {
-    #any channel or version that starts with the specified versions
-    case "$1" in
-        ( "1"* | "2"* | "3"*  | "4"* | "5"*) 
-            echo false
-            return 0
+    # Extract the major version by splitting on the dot
+    major_version="${1%%.*}"
+
+    # Check if the major version is a valid number and less than 6
+    case "$major_version" in
+        [0-9]*)  
+            if [ "$major_version" -lt 6 ]; then
+                echo false
+                return 0
+            fi
+            ;;
     esac
 
     echo true
@@ -950,6 +956,37 @@ get_absolute_path() {
     return 0
 }
 
+# args:
+# override - $1 (boolean, true or false)
+get_cp_options() {
+    eval $invocation
+
+    local override="$1"
+    local override_switch=""
+
+    if [ "$override" = false ]; then
+        override_switch="-n"
+
+        # create temporary files to check if 'cp -u' is supported
+        tmp_dir="$(mktemp -d)"
+        tmp_file="$tmp_dir/testfile"
+        tmp_file2="$tmp_dir/testfile2"
+
+        touch "$tmp_file"
+
+        # use -u instead of -n if it's available
+        if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then
+            override_switch="-u"
+        fi
+
+        # clean up
+        rm -f "$tmp_file" "$tmp_file2"
+        rm -rf "$tmp_dir"
+    fi
+
+    echo "$override_switch"
+}
+
 # args:
 # input_files - stdin
 # root_path - $1
@@ -961,15 +998,7 @@ copy_files_or_dirs_from_list() {
     local root_path="$(remove_trailing_slash "$1")"
     local out_path="$(remove_trailing_slash "$2")"
     local override="$3"
-    local osname="$(get_current_os_name)"
-    local override_switch=$(
-        if [ "$override" = false ]; then
-            if [ "$osname" = "linux-musl" ]; then
-                printf -- "-u";
-            else
-                printf -- "-n";
-            fi
-        fi)
+    local override_switch="$(get_cp_options "$override")"
 
     cat | uniq | while read -r file_path; do
         local path="$(remove_beginning_slash "${file_path#$root_path}")"
@@ -1243,6 +1272,61 @@ downloadwget() {
     return 0
 }
 
+extract_stem() {
+    local url="$1"
+    # extract the protocol
+    proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
+    # remove the protocol
+    url="${1/$proto/}"
+    # extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path
+    full_path="$(echo $url | grep / | cut -d/ -f2-)"
+    path="$(echo $full_path | cut -d/ -f2-)"
+    echo $path
+}
+
+check_url_exists() {
+    eval $invocation
+    local url="$1"
+
+    local code=""
+    if machine_has "curl"
+    then
+        code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url");
+    elif machine_has "wget"
+    then
+        # get the http response, grab the status code
+        server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1)
+        code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}')
+    fi
+    if [ $code = "200" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+sanitize_redirect_url() {
+    eval $invocation
+
+    local url_stem
+    url_stem=$(extract_stem "$1")
+    say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}"
+
+    for feed in "${feeds[@]}"
+    do
+        local trial_url="$feed/$url_stem"
+        say_verbose "Checking ${yellow:-}$trial_url${normal:-}"
+        if check_url_exists "$trial_url"; then
+            say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}"
+            echo "$trial_url"
+            return 0
+        else
+            say_verbose "No match at ${yellow:-}$trial_url${normal:-}"
+        fi
+    done
+    return 1
+}
+
 get_download_link_from_aka_ms() {
     eval $invocation
 
@@ -1295,6 +1379,11 @@ get_download_link_from_aka_ms() {
             return 1
         fi
 
+        sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link")
+        if [[ -n "$sanitized_redirect_url" ]]; then
+            aka_ms_download_link="$sanitized_redirect_url"
+        fi
+
         say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
         return 0
     else
@@ -1306,7 +1395,9 @@ get_download_link_from_aka_ms() {
 get_feeds_to_use()
 {
     feeds=(
+    "https://builds.dotnet.microsoft.com/dotnet"
     "https://dotnetcli.azureedge.net/dotnet"
+    "https://ci.dot.net/public"
     "https://dotnetbuilds.azureedge.net/public"
     )
 
@@ -1735,7 +1826,7 @@ do
             zip_path="$1"
             ;;
         -?|--?|-h|--help|-[Hh]elp)
-            script_name="$(basename "$0")"
+            script_name="dotnet-install.sh"
             echo ".NET Tools Installer"
             echo "Usage:"
             echo "       # Install a .NET SDK of a given Quality from a given Channel"
@@ -1865,4 +1956,4 @@ fi
 
 say "Note that the script does not resolve dependencies during installation."
 say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
-say "Installation finished successfully."
+say "Installation finished successfully."
\ No newline at end of file
diff --git a/src/nvidia-cuda/devcontainer-feature.json b/src/nvidia-cuda/devcontainer-feature.json
index b46d7c433..d29074fd9 100644
--- a/src/nvidia-cuda/devcontainer-feature.json
+++ b/src/nvidia-cuda/devcontainer-feature.json
@@ -1,6 +1,6 @@
 {
   "id": "nvidia-cuda",
-  "version": "1.1.3",
+  "version": "1.2.0",
   "name": "NVIDIA CUDA",
   "description": "Installs shared libraries for NVIDIA CUDA.",
   "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda",
@@ -48,6 +48,7 @@
     "cudnnVersion": {
       "type": "string",
       "proposals": [
+        "automatic",
         "8.9.5.29",
         "8.9.4.25",
         "8.9.3.28",
@@ -79,7 +80,7 @@
         "9.3.0.75",
         "9.4.0.58"
       ],
-      "default": "8.6.0.163",
+      "default": "automatic",
       "description": "Version of cuDNN to install"
     }
   },
diff --git a/src/nvidia-cuda/install.sh b/src/nvidia-cuda/install.sh
index 37ba7f0f4..1cfc7668e 100644
--- a/src/nvidia-cuda/install.sh
+++ b/src/nvidia-cuda/install.sh
@@ -59,8 +59,6 @@ apt-get update -yq
 cuda_pkg="cuda-libraries-${CUDA_VERSION/./-}"
 nvtx_pkg="cuda-nvtx-${CUDA_VERSION/./-}"
 toolkit_pkg="cuda-toolkit-${CUDA_VERSION/./-}"
-major_cudnn_version=$(echo "${CUDNN_VERSION}" | cut -d '.' -f 1)
-major_cuda_version=$(echo "${CUDA_VERSION}" | cut -d '.' -f 1)
 if ! apt-cache show "$cuda_pkg"; then
     echo "The requested version of CUDA is not available: CUDA $CUDA_VERSION"
     exit 1
@@ -68,11 +66,23 @@ fi
 
 echo "Installing CUDA libraries..."
 apt-get install -yq "$cuda_pkg"
+apt-get update -yq --fix-missing
+
+# auto find recent cudnn version
+major_cuda_version=$(echo "${CUDA_VERSION}" | cut -d '.' -f 1)
+if [ "$CUDNN_VERSION" = "automatic" ]; then
+    if [[ "$CUDA_VERSION" < "12.3" ]]; then
+        CUDNN_VERSION=$(apt-cache policy libcudnn8 | grep "$CUDA_VERSION" | grep -Eo '^[^-1+]*' | sort -V | tail -n1 | xargs)
+    else
+        CUDNN_VERSION=$(apt-cache policy libcudnn9-cuda-$major_cuda_version | grep "Candidate" | awk '{print $2}' | grep -Eo '^[^-1+]*')
+    fi
+fi
+major_cudnn_version=$(echo "${CUDNN_VERSION}" | cut -d '.' -f 1)
 
 if [ "$INSTALL_CUDNN" = "true" ]; then
     # Ensure that the requested version of cuDNN is available AND compatible
-    #if major cudnn version is 9, then we need to install libcudnn9-cuda-<major_version> package
-    #else we need to install libcudnn8-cuda-<major_version> package
+    #if major cudnn version is 9, then we need to install libcudnn9-cuda-<major_cuda_version>_<CUDNN_VERSION>-1 package
+    #else we need to install libcudnn8_<CUDNN_VERSION>-1+cuda<CUDA_VERSION>" package
     if [[ $major_cudnn_version -ge "9" ]]
     then
         cudnn_pkg_version="libcudnn9-cuda-${major_cuda_version}=${CUDNN_VERSION}-1"
@@ -91,13 +101,14 @@ fi
 
 if [ "$INSTALL_CUDNNDEV" = "true" ]; then
     # Ensure that the requested version of cuDNN development package is available AND compatible
+    #if major cudnn version is 9, then we need to install libcudnn9-dev-cuda-<major_cuda_version>_<CUDNN_VERSION>-1 package
+    #else we need to install libcudnn8-dev_<CUDNN_VERSION>-1+cuda<CUDA_VERSION>" package
     if [[ $major_cudnn_version -ge "9" ]]
     then
         cudnn_dev_pkg_version="libcudnn9-dev-cuda-${major_cuda_version}=${CUDNN_VERSION}-1"
     else
         cudnn_dev_pkg_version="libcudnn8-dev=${CUDNN_VERSION}-1+cuda${CUDA_VERSION}"
     fi
-    
     if ! apt-cache show "$cudnn_dev_pkg_version"; then
         echo "The requested version of cuDNN development package is not available: cuDNN $CUDNN_VERSION for CUDA $CUDA_VERSION"
         exit 1
diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json
index 1a3ee1b2f..ab9a8e782 100644
--- a/src/oryx/devcontainer-feature.json
+++ b/src/oryx/devcontainer-feature.json
@@ -1,6 +1,6 @@
 {
     "id": "oryx",
-    "version": "1.3.7",
+    "version": "1.4.0",
     "name": "Oryx",
     "description": "Installs the oryx CLI",
     "documentationURL": "https://github.com/devcontainers/features/tree/main/src/oryx",
diff --git a/src/oryx/scripts/vendor/dotnet-install.sh b/src/oryx/scripts/vendor/dotnet-install.sh
index 38a160cf1..122ee68ed 100755
--- a/src/oryx/scripts/vendor/dotnet-install.sh
+++ b/src/oryx/scripts/vendor/dotnet-install.sh
@@ -423,11 +423,17 @@ get_normalized_architecture_for_specific_sdk_version() {
 # args:
 # version or channel - $1
 is_arm64_supported() {
-    #any channel or version that starts with the specified versions
-    case "$1" in
-        ( "1"* | "2"* | "3"*  | "4"* | "5"*) 
-            echo false
-            return 0
+    # Extract the major version by splitting on the dot
+    major_version="${1%%.*}"
+
+    # Check if the major version is a valid number and less than 6
+    case "$major_version" in
+        [0-9]*)  
+            if [ "$major_version" -lt 6 ]; then
+                echo false
+                return 0
+            fi
+            ;;
     esac
 
     echo true
@@ -950,6 +956,37 @@ get_absolute_path() {
     return 0
 }
 
+# args:
+# override - $1 (boolean, true or false)
+get_cp_options() {
+    eval $invocation
+
+    local override="$1"
+    local override_switch=""
+
+    if [ "$override" = false ]; then
+        override_switch="-n"
+
+        # create temporary files to check if 'cp -u' is supported
+        tmp_dir="$(mktemp -d)"
+        tmp_file="$tmp_dir/testfile"
+        tmp_file2="$tmp_dir/testfile2"
+
+        touch "$tmp_file"
+
+        # use -u instead of -n if it's available
+        if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then
+            override_switch="-u"
+        fi
+
+        # clean up
+        rm -f "$tmp_file" "$tmp_file2"
+        rm -rf "$tmp_dir"
+    fi
+
+    echo "$override_switch"
+}
+
 # args:
 # input_files - stdin
 # root_path - $1
@@ -961,15 +998,7 @@ copy_files_or_dirs_from_list() {
     local root_path="$(remove_trailing_slash "$1")"
     local out_path="$(remove_trailing_slash "$2")"
     local override="$3"
-    local osname="$(get_current_os_name)"
-    local override_switch=$(
-        if [ "$override" = false ]; then
-            if [ "$osname" = "linux-musl" ]; then
-                printf -- "-u";
-            else
-                printf -- "-n";
-            fi
-        fi)
+    local override_switch="$(get_cp_options "$override")"
 
     cat | uniq | while read -r file_path; do
         local path="$(remove_beginning_slash "${file_path#$root_path}")"
@@ -1243,6 +1272,61 @@ downloadwget() {
     return 0
 }
 
+extract_stem() {
+    local url="$1"
+    # extract the protocol
+    proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
+    # remove the protocol
+    url="${1/$proto/}"
+    # extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path
+    full_path="$(echo $url | grep / | cut -d/ -f2-)"
+    path="$(echo $full_path | cut -d/ -f2-)"
+    echo $path
+}
+
+check_url_exists() {
+    eval $invocation
+    local url="$1"
+
+    local code=""
+    if machine_has "curl"
+    then
+        code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url");
+    elif machine_has "wget"
+    then
+        # get the http response, grab the status code
+        server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1)
+        code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}')
+    fi
+    if [ $code = "200" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+sanitize_redirect_url() {
+    eval $invocation
+
+    local url_stem
+    url_stem=$(extract_stem "$1")
+    say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}"
+
+    for feed in "${feeds[@]}"
+    do
+        local trial_url="$feed/$url_stem"
+        say_verbose "Checking ${yellow:-}$trial_url${normal:-}"
+        if check_url_exists "$trial_url"; then
+            say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}"
+            echo "$trial_url"
+            return 0
+        else
+            say_verbose "No match at ${yellow:-}$trial_url${normal:-}"
+        fi
+    done
+    return 1
+}
+
 get_download_link_from_aka_ms() {
     eval $invocation
 
@@ -1295,6 +1379,11 @@ get_download_link_from_aka_ms() {
             return 1
         fi
 
+        sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link")
+        if [[ -n "$sanitized_redirect_url" ]]; then
+            aka_ms_download_link="$sanitized_redirect_url"
+        fi
+
         say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
         return 0
     else
@@ -1306,7 +1395,9 @@ get_download_link_from_aka_ms() {
 get_feeds_to_use()
 {
     feeds=(
+    "https://builds.dotnet.microsoft.com/dotnet"
     "https://dotnetcli.azureedge.net/dotnet"
+    "https://ci.dot.net/public"
     "https://dotnetbuilds.azureedge.net/public"
     )
 
@@ -1735,7 +1826,7 @@ do
             zip_path="$1"
             ;;
         -?|--?|-h|--help|-[Hh]elp)
-            script_name="$(basename "$0")"
+            script_name="dotnet-install.sh"
             echo ".NET Tools Installer"
             echo "Usage:"
             echo "       # Install a .NET SDK of a given Quality from a given Channel"
@@ -1865,4 +1956,4 @@ fi
 
 say "Note that the script does not resolve dependencies during installation."
 say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
-say "Installation finished successfully."
+say "Installation finished successfully."
\ No newline at end of file
diff --git a/test/dotnet/dotnet_helpers.sh b/test/dotnet/dotnet_helpers.sh
index a24bd1ce2..01e554f66 100644
--- a/test/dotnet/dotnet_helpers.sh
+++ b/test/dotnet/dotnet_helpers.sh
@@ -9,11 +9,11 @@ fetch_latest_version_in_channel() {
     local channel="$1"
     local runtime="$2"
     if [ "$runtime" = "dotnet" ]; then
-        wget -qO- "https://dotnetcli.azureedge.net/dotnet/Runtime/$channel/latest.version"
+        wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Runtime/$channel/latest.version"
     elif [ "$runtime" = "aspnetcore" ]; then
-        wget -qO- "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$channel/latest.version"
+        wget -qO- "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$channel/latest.version"
     else
-        wget -qO- "https://dotnetcli.azureedge.net/dotnet/Sdk/$channel/latest.version"
+        wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Sdk/$channel/latest.version"
     fi
 }
 
diff --git a/test/dotnet/install_dotnet_latest_when_version_is_empty.sh b/test/dotnet/install_dotnet_latest_when_version_is_empty.sh
index cd23edcf1..b28c45a2f 100644
--- a/test/dotnet/install_dotnet_latest_when_version_is_empty.sh
+++ b/test/dotnet/install_dotnet_latest_when_version_is_empty.sh
@@ -18,9 +18,6 @@ expected=$(fetch_latest_version)
 check "Latest .NET SDK version installed" \
 is_dotnet_sdk_version_installed "$expected"
 
-check "Build and run example project" \
-dotnet run --project projects/net8.0
-
 # Report results
 # If any of the checks above exited with a non-zero exit code, the test will fail.
 reportResults
\ No newline at end of file
diff --git a/test/dotnet/install_dotnet_lts.sh b/test/dotnet/install_dotnet_lts.sh
index bc2d40782..da9175c15 100644
--- a/test/dotnet/install_dotnet_lts.sh
+++ b/test/dotnet/install_dotnet_lts.sh
@@ -18,9 +18,6 @@ expected=$(fetch_latest_version_in_channel "LTS")
 check "Latest LTS version installed" \
 is_dotnet_sdk_version_installed "$expected"
 
-check "Build and run example project" \
-dotnet run --project projects/net8.0
-
 # Report results
 # If any of the checks above exited with a non-zero exit code, the test will fail.
 reportResults
\ No newline at end of file
diff --git a/test/dotnet/install_dotnet_multiple_versions.sh b/test/dotnet/install_dotnet_multiple_versions.sh
index 5f0f12533..87bf8caf4 100644
--- a/test/dotnet/install_dotnet_multiple_versions.sh
+++ b/test/dotnet/install_dotnet_multiple_versions.sh
@@ -13,6 +13,9 @@ source dev-container-features-test-lib
 source dotnet_env.sh
 source dotnet_helpers.sh
 
+check ".NET SDK 9.0 installed" \
+is_dotnet_sdk_version_installed "9.0"
+
 check ".NET SDK 8.0 installed" \
 is_dotnet_sdk_version_installed "8.0"
 
@@ -22,9 +25,33 @@ is_dotnet_sdk_version_installed "7.0"
 check ".NET SDK 6.0 installed" \
 is_dotnet_sdk_version_installed "6.0"
 
+check ".NET SDK 5.0 installed" \
+is_dotnet_sdk_version_installed "5.0"
+
+check ".NET Core SDK 3.1 installed" \
+is_dotnet_sdk_version_installed "3.1"
+
 check "Build example class library" \
 dotnet build projects/multitargeting
 
+check "Build and run .NET 9.0 project" \
+dotnet run --project projects/net9.0
+
+check "Build and run .NET 8.0 project" \
+dotnet run --project projects/net8.0
+
+check "Build and run .NET 7.0 project" \
+dotnet run --project projects/net7.0
+
+check "Build and run .NET 6.0 project" \
+dotnet run --project projects/net6.0
+
+check "Build and run .NET 5.0 project" \
+dotnet run --project projects/net5.0
+
+check "Build and run .NET Core 3.1 project" \
+dotnet run --project projects/netcoreapp3.1
+
 # Report results
 # If any of the checks above exited with a non-zero exit code, the test will fail.
 reportResults
\ No newline at end of file
diff --git a/test/dotnet/projects/multitargeting/example_classlib.csproj b/test/dotnet/projects/multitargeting/example_classlib.csproj
index ba47b0f46..8a8ca0c32 100644
--- a/test/dotnet/projects/multitargeting/example_classlib.csproj
+++ b/test/dotnet/projects/multitargeting/example_classlib.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>net8.0;net7.0;net6.0</TargetFrameworks>
+    <TargetFrameworks>net9.0;net8.0;net7.0;net6.0</TargetFrameworks>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
   </PropertyGroup>
diff --git a/test/dotnet/projects/net5.0/example_project.csproj b/test/dotnet/projects/net5.0/example_project.csproj
index 63450c349..9fa0cf3f7 100644
--- a/test/dotnet/projects/net5.0/example_project.csproj
+++ b/test/dotnet/projects/net5.0/example_project.csproj
@@ -7,7 +7,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
   </ItemGroup>
 
 </Project>
\ No newline at end of file
diff --git a/test/dotnet/projects/net6.0/example_project.csproj b/test/dotnet/projects/net6.0/example_project.csproj
index aa2434cb7..48c9b4e8a 100644
--- a/test/dotnet/projects/net6.0/example_project.csproj
+++ b/test/dotnet/projects/net6.0/example_project.csproj
@@ -8,7 +8,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
   </ItemGroup>
 
 </Project>
\ No newline at end of file
diff --git a/test/dotnet/projects/net7.0/example_project.csproj b/test/dotnet/projects/net7.0/example_project.csproj
index 424f54ae7..11953d275 100644
--- a/test/dotnet/projects/net7.0/example_project.csproj
+++ b/test/dotnet/projects/net7.0/example_project.csproj
@@ -8,7 +8,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
   </ItemGroup>
 
 </Project>
\ No newline at end of file
diff --git a/test/dotnet/projects/net8.0/example_project.csproj b/test/dotnet/projects/net8.0/example_project.csproj
index 2f1f60891..ddac9409e 100644
--- a/test/dotnet/projects/net8.0/example_project.csproj
+++ b/test/dotnet/projects/net8.0/example_project.csproj
@@ -8,7 +8,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
   </ItemGroup>
 
 </Project>
\ No newline at end of file
diff --git a/test/dotnet/projects/net9.0/Program.cs b/test/dotnet/projects/net9.0/Program.cs
new file mode 100644
index 000000000..59fb426af
--- /dev/null
+++ b/test/dotnet/projects/net9.0/Program.cs
@@ -0,0 +1,32 @@
+using Newtonsoft.Json;
+
+string json = """
+{
+  "Name": "Inception",
+  "ReleaseDate": "2010-07-08T00:00:00",
+  "Genres": [
+    "Action",
+    "Thriller"
+  ]
+}
+""";
+
+Movie? m = JsonConvert.DeserializeObject<Movie>(json);
+
+if (m == default)
+{
+    Console.WriteLine("Decoding failed!");
+}
+else
+{
+    Console.WriteLine($"Movie name: {m.Name}");
+    Console.WriteLine($"Release Date: {m.ReleaseDate}");
+    Console.WriteLine($"Genres: {string.Join(", ", m.Genres)}");
+}
+
+class Movie(string? name, DateTime releaseDate, List<string>? genres)
+{
+    public string Name { get; set; } = name ?? "Default Name";
+    public DateTime ReleaseDate { get; set; } = releaseDate;
+    public List<string> Genres { get; set; } = genres ?? [];
+}
\ No newline at end of file
diff --git a/test/dotnet/projects/net9.0/example_project.csproj b/test/dotnet/projects/net9.0/example_project.csproj
new file mode 100644
index 000000000..6cc1da0d0
--- /dev/null
+++ b/test/dotnet/projects/net9.0/example_project.csproj
@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net9.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+  </ItemGroup>
+
+</Project>
\ No newline at end of file
diff --git a/test/dotnet/projects/netcoreapp3.1/example_project.csproj b/test/dotnet/projects/netcoreapp3.1/example_project.csproj
index e2e909c17..f8859db8b 100644
--- a/test/dotnet/projects/netcoreapp3.1/example_project.csproj
+++ b/test/dotnet/projects/netcoreapp3.1/example_project.csproj
@@ -3,12 +3,11 @@
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <TargetFramework>netcoreapp3.1</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
   </ItemGroup>
 
 </Project>
\ No newline at end of file
diff --git a/test/dotnet/scenarios.json b/test/dotnet/scenarios.json
index 2fd74f587..641753632 100644
--- a/test/dotnet/scenarios.json
+++ b/test/dotnet/scenarios.json
@@ -40,10 +40,13 @@
         "remoteUser": "vscode",
         "features": {
             "dotnet": {
-                "version": "8.0.100-preview.6.23330.14",
+                "version": "9.0",
                 "additionalVersions": [
+                    "8.0",
                     "7.0",
-                    "6.0"
+                    "6.0",
+                    "5.0",
+                    "3.1"
                 ]
             }
         }
@@ -92,4 +95,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/test/dotnet/test.sh b/test/dotnet/test.sh
index 50d79941f..11cc73126 100644
--- a/test/dotnet/test.sh
+++ b/test/dotnet/test.sh
@@ -24,9 +24,6 @@ expected=$(fetch_latest_version)
 check "Latest .NET SDK version installed" \
 is_dotnet_sdk_version_installed "$expected"
 
-check "Build and run example project" \
-dotnet run --project projects/net8.0
-
 # Report results
 # If any of the checks above exited with a non-zero exit code, the test will fail.
 reportResults
\ No newline at end of file
diff --git a/test/nvidia-cuda/install_cuda_12_3_version.sh b/test/nvidia-cuda/install_cuda_12_3_version.sh
new file mode 100644
index 000000000..95d4e8bdc
--- /dev/null
+++ b/test/nvidia-cuda/install_cuda_12_3_version.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+# Optional: Import test library
+source dev-container-features-test-lib
+
+# # Check installation of libcudnn9-cuda-12 (9.4.0)
+check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)"
+
+# Check installation of cuda-nvtx-12-3 (12.3)
+check "cuda-12-3+nvtx" test -e '/usr/local/cuda-12.3/targets/x86_64-linux/include/nvtx3/'
+
+# Report result
+reportResults
diff --git a/test/nvidia-cuda/install_cuda_12_4_version.sh b/test/nvidia-cuda/install_cuda_12_4_version.sh
new file mode 100644
index 000000000..77ecbf190
--- /dev/null
+++ b/test/nvidia-cuda/install_cuda_12_4_version.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+# Optional: Import test library
+source dev-container-features-test-lib
+
+# # Check installation of libcudnn9-cuda-12 (9.4.0)
+check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)"
+
+# Check installation of cuda-nvtx-12-4 (12.4)
+check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3/'
+
+# Report result
+reportResults
diff --git a/test/nvidia-cuda/install_cuda_12_5_version.sh b/test/nvidia-cuda/install_cuda_12_5_version.sh
new file mode 100644
index 000000000..05cd20c88
--- /dev/null
+++ b/test/nvidia-cuda/install_cuda_12_5_version.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+
+# Optional: Import test library
+source dev-container-features-test-lib
+
+# # Check installation of libcudnn9-cuda-12 (9.4.0)
+check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)"
+
+# Check installation of cuda-nvtx-12-5 (12.5)
+check "cuda-12-5+nvtx" test -e '/usr/local/cuda-12.5/targets/x86_64-linux/include/nvtx3/'
+
+# Report result
+reportResults
diff --git a/test/nvidia-cuda/install_cudnn_123_version.sh b/test/nvidia-cuda/install_cudnn_123_version.sh
deleted file mode 100644
index f331a591f..000000000
--- a/test/nvidia-cuda/install_cudnn_123_version.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# Optional: Import test library
-source dev-container-features-test-lib
-
-# Check installation of libcudnn9-cuda-12 (9.4.0)
-check "libcudnn.so.9.4.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.4.0' | wc -l)"
-
-# Check installation of cuda-nvtx-11-7 (11.7)
-# check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3'
-
-# Report result
-reportResults
-    
\ No newline at end of file
diff --git a/test/nvidia-cuda/install_cudnn_124_version.sh b/test/nvidia-cuda/install_cudnn_124_version.sh
deleted file mode 100644
index f331a591f..000000000
--- a/test/nvidia-cuda/install_cudnn_124_version.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# Optional: Import test library
-source dev-container-features-test-lib
-
-# Check installation of libcudnn9-cuda-12 (9.4.0)
-check "libcudnn.so.9.4.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.4.0' | wc -l)"
-
-# Check installation of cuda-nvtx-11-7 (11.7)
-# check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3'
-
-# Report result
-reportResults
-    
\ No newline at end of file
diff --git a/test/nvidia-cuda/install_cudnn_latest_version.sh b/test/nvidia-cuda/install_cudnn_latest_version.sh
deleted file mode 100644
index f331a591f..000000000
--- a/test/nvidia-cuda/install_cudnn_latest_version.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# Optional: Import test library
-source dev-container-features-test-lib
-
-# Check installation of libcudnn9-cuda-12 (9.4.0)
-check "libcudnn.so.9.4.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.4.0' | wc -l)"
-
-# Check installation of cuda-nvtx-11-7 (11.7)
-# check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3'
-
-# Report result
-reportResults
-    
\ No newline at end of file
diff --git a/test/nvidia-cuda/scenarios.json b/test/nvidia-cuda/scenarios.json
index d2400503b..82c84f119 100644
--- a/test/nvidia-cuda/scenarios.json
+++ b/test/nvidia-cuda/scenarios.json
@@ -16,47 +16,41 @@
             "nvidia-cuda": {
                 "installCudnn": true,
                 "installNvtx": true,
-                "cudaVersion": "11.7",
-                "cudnnVersion": "8.5.0.96"
+                "cudaVersion": "11.7"
             }
         }
     },
-    "install_cudnn_123_version": {
+    "install_cuda_12_3_version": {
         "image": "debian",
         "features": {
             "nvidia-cuda": {
                 "installCudnn": true,
-                "installNvtx": true,
                 "installCudnnDev": true,
-                "installToolkit": true,
-                "cudaVersion": "12.3",
-                "cudnnVersion": "9.4.0.58"
+                "installNvtx": true,
+                "cudaVersion": "12.3"
             }
         }
     },
-    "install_cudnn_124_version": {
+    "install_cuda_12_4_version": {
         "image": "debian",
         "features": {
             "nvidia-cuda": {
                 "installCudnn": true,
-                "installNvtx": true,
                 "installCudnnDev": true,
-                "installToolkit": true,
-                "cudaVersion": "12.4",
-                "cudnnVersion": "9.4.0.58"
+                "installNvtx": true,
+                "cudaVersion": "12.4"
             }
         }
     },
-    "install_cudnn_latest_version": {
+    "install_cuda_12_5_version": {
         "image": "debian",
         "features": {
             "nvidia-cuda": {
                 "installCudnn": true,
-                "installNvtx": true,
                 "installCudnnDev": true,
-                "installToolkit": true,
+                "installNvtx": true,
                 "cudaVersion": "12.5",
-                "cudnnVersion": "9.4.0.58"
+                "cudnnVersion": "9.5.0.50"
             }
         }
     }