diff --git a/src/Tasks/CacheGet.cs b/src/Tasks/CacheGet.cs
new file mode 100644
index 00000000000..db18482318d
--- /dev/null
+++ b/src/Tasks/CacheGet.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Build.Framework;
+
+#nullable disable
+
+namespace Microsoft.Build.Tasks
+{
+ public class CacheGet : TaskExtension
+ {
+ [Required]
+ public string Key { get; set; }
+
+ [Output]
+ public string Value { get; set; }
+
+ public override bool Execute()
+ {
+ Value = (string)BuildEngine4.GetRegisteredTaskObject(Key, RegisteredTaskObjectLifetime.Build) ?? "";
+ return true;
+ }
+ }
+}
diff --git a/src/Tasks/CacheSet.cs b/src/Tasks/CacheSet.cs
new file mode 100644
index 00000000000..02ed153f6a5
--- /dev/null
+++ b/src/Tasks/CacheSet.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Build.Framework;
+
+#nullable disable
+
+namespace Microsoft.Build.Tasks
+{
+ public class CacheSet : TaskExtension
+ {
+ [Required]
+ public string Key { get; set; }
+
+ [Required]
+ public string Value { get; set; }
+
+ public override bool Execute()
+ {
+ BuildEngine4.RegisterTaskObject(Key, Value, RegisteredTaskObjectLifetime.Build, allowEarlyCollection: true);
+ return true;
+ }
+ }
+}
diff --git a/src/Tasks/Microsoft.Build.Tasks.csproj b/src/Tasks/Microsoft.Build.Tasks.csproj
index a518f22fe8b..7fb86403277 100644
--- a/src/Tasks/Microsoft.Build.Tasks.csproj
+++ b/src/Tasks/Microsoft.Build.Tasks.csproj
@@ -204,6 +204,8 @@
+
+