diff --git a/doc/news/DM-47363.feature.rst b/doc/news/DM-47363.feature.rst
new file mode 100644
index 000000000..d6669a1ac
--- /dev/null
+++ b/doc/news/DM-47363.feature.rst
@@ -0,0 +1 @@
+Add new `set_dof.py`` to set absolute DOF position
\ No newline at end of file
diff --git a/python/lsst/ts/standardscripts/data/scripts/maintel/set_dof.py b/python/lsst/ts/standardscripts/data/scripts/maintel/set_dof.py
new file mode 100755
index 000000000..f3c48b07d
--- /dev/null
+++ b/python/lsst/ts/standardscripts/data/scripts/maintel/set_dof.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# This file is part of ts_standardscripts
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+import asyncio
+
+from lsst.ts.standardscripts.maintel import SetDOF
+
+asyncio.run(SetDOF.amain())
diff --git a/python/lsst/ts/standardscripts/maintel/__init__.py b/python/lsst/ts/standardscripts/maintel/__init__.py
index 9017f90d7..27c01a834 100644
--- a/python/lsst/ts/standardscripts/maintel/__init__.py
+++ b/python/lsst/ts/standardscripts/maintel/__init__.py
@@ -39,6 +39,7 @@
 from .offset_mtcs import *
 from .open_mirror_covers import *
 from .point_azel import *
+from .set_dof import *
 from .setup_mtcs import *
 from .standby_comcam import *
 from .standby_mtcs import *
diff --git a/python/lsst/ts/standardscripts/maintel/set_dof.py b/python/lsst/ts/standardscripts/maintel/set_dof.py
new file mode 100644
index 000000000..d574dc055
--- /dev/null
+++ b/python/lsst/ts/standardscripts/maintel/set_dof.py
@@ -0,0 +1,461 @@
+# This file is part of ts_standardscripts
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+__all__ = ["SetDOF"]
+
+import typing
+
+import numpy as np
+import yaml
+from lsst.ts import salobj
+from lsst.ts.observatory.control.maintel.mtcs import MTCS
+from lsst.ts.observatory.control.utils.enums import DOFName
+
+STD_TIMEOUT = 30
+
+class SetDOF(salobj.BaseScript):
+    """Set absolute positions DOF to the main telescope, either bending
+    mode or hexapod position.
+
+    Parameters
+    ----------
+    index : `int`
+        Index of Script SAL component.
+
+    Notes
+    -----
+    **Checkpoints**
+    "Setting DOF..." - The DOF absolute position is being applied.
+
+    """
+
+    def __init__(self, index) -> None:
+        super().__init__(
+            index=index,
+            descr="Set absolute degrees of freedom position of the main telescope.",
+        )
+
+        # Create the MTCS object
+        self.mtcs = None
+
+        # Create the DOF vector
+        self.dofs = np.zeros(len(DOFName))
+
+    async def configure_tcs(self) -> None:
+        """Handle creating MTCS object and waiting for remote to start."""
+        if self.mtcs is None:
+            self.log.debug("Creating MTCS.")
+            self.mtcs = MTCS(
+                domain=self.domain,
+                log=self.log,
+            )
+            await self.mtcs.start_task
+        else:
+            self.log.debug("MTCS already defined, skipping.")
+
+    @classmethod
+    def get_schema(cls) -> typing.Dict[str, typing.Any]:
+        schema_yaml = """
+            $schema: http://json-schema.org/draft-07/schema#
+            $id: https://github.com/lsst-ts/ts_standardscripts/maintel/SetDOF.yaml
+            title: SetDOF v1
+            description: Configuration for SetDOF Script.
+            type: object
+            properties:
+              dofs:
+                type: array
+                description: >-
+                  Defines a 50-dimensional vector for all DOFs, combining M2,
+                  Camera, M1M3, and M2 bending modes. This overrides individual DOF inputs.
+                  First 5 elements for M2, next 5 for Camera, next 20 for M1M3 bending modes,
+                  last 20 for M2 bending modes. Units: microns or arcsec.
+                items:
+                  type: number
+                minItems: 50
+                maxItems: 50
+              M2_dz:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 hexapod in the z direction.
+                    Units in um.
+                  default: 0.0
+              M2_dx:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 hexapod in the x direction.
+                    Units in um.
+                  default: 0.0
+              M2_dy:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 hexapod in the y direction.
+                    Units in um.
+                  default: 0.0
+              M2_rx:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 hexapod in rx.
+                    Units in arcsec.
+                  default: 0.0
+              M2_ry:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 hexapod in ry.
+                    Units in arcsec.
+                  default: 0.0
+              Cam_dz:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the Camera hexapod in
+                    the z direction. Units in um.
+                  default: 0.0
+              Cam_dx:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the Camera hexapod
+                    in the x direction. Units in um.
+                  default: 0.0
+              Cam_dy:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the Camera hexapod in
+                    the y direction. Units in um.
+                  default: 0.0
+              Cam_rx:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the Camera hexapod in rx.
+                    Units in arcsec.
+                  default: 0.0
+              Cam_ry:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the Camera hexapod in ry.
+                    Units in arcsec.
+                  default: 0.0
+              M1M3_B1:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 1.
+                    Units in um.
+                  default: 0.0
+              M1M3_B2:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 2.
+                    Units in um.
+                  default: 0.0
+              M1M3_B3:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 3.
+                    Units in um.
+                  default: 0.0
+              M1M3_B4:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 4.
+                    Units in um.
+                  default: 0.0
+              M1M3_B5:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 5.
+                    Units in um.
+                  default: 0.0
+              M1M3_B6:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 6.
+                    Units in um.
+                  default: 0.0
+              M1M3_B7:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 7.
+                    Units in um.
+                  default: 0.0
+              M1M3_B8:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 8.
+                    Units in um.
+                  default: 0.0
+              M1M3_B9:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 9.
+                    Units in um.
+                  default: 0.0
+              M1M3_B10:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 10.
+                    Units in um.
+                  default: 0.0
+              M1M3_B11:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 11.
+                    Units in um.
+                  default: 0.0
+              M1M3_B12:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 12.
+                    Units in um.
+                  default: 0.0
+              M1M3_B13:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 13.
+                    Units in um.
+                  default: 0.0
+              M1M3_B14:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 14.
+                    Units in um.
+                  default: 0.0
+              M1M3_B15:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 15.
+                    Units in um.
+                  default: 0.0
+              M1M3_B16:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 16.
+                    Units in um.
+                  default: 0.0
+              M1M3_B17:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 17.
+                    Units in um.
+                  default: 0.0
+              M1M3_B18:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 18.
+                    Units in um.
+                  default: 0.0
+              M1M3_B19:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 19.
+                    Units in um.
+                  default: 0.0
+              M1M3_B20:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M1M3 bending mode 20.
+                    Units in um.
+                  default: 0.0
+              M2_B1:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 1.
+                    Units in um.
+                  default: 0.0
+              M2_B2:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 2.
+                    Units in um.
+                  default: 0.0
+              M2_B3:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 3.
+                    Units in um.
+                  default: 0.0
+              M2_B4:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 4.
+                    Units in um.
+                  default: 0.0
+              M2_B5:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 5.
+                    Units in um.
+                  default: 0.0
+              M2_B6:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 6.
+                    Units in um.
+                  default: 0.0
+              M2_B7:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 7.
+                    Units in um.
+                  default: 0.0
+              M2_B8:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 8.
+                    Units in um.
+                  default: 0.0
+              M2_B9:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 9.
+                    Units in um.
+                  default: 0.0
+              M2_B10:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 10.
+                    Units in um.
+                  default: 0.0
+              M2_B11:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 11.
+                    Units in um.
+                  default: 0.0
+              M2_B12:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 12.
+                    Units in um.
+                  default: 0.0
+              M2_B13:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 13.
+                    Units in um.
+                  default: 0.0
+              M2_B14:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 14.
+                    Units in um.
+                  default: 0.0
+              M2_B15:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 15.
+                    Units in um.
+                  default: 0.0
+              M2_B16:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 16.
+                    Units in um.
+                  default: 0.0
+              M2_B17:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 17.
+                    Units in um.
+                  default: 0.0
+              M2_B18:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 18.
+                    Units in um.
+                  default: 0.0
+              M2_B19:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 19.
+                    Units in um.
+                  default: 0.0
+              M2_B20:
+                  type: number
+                  description: >-
+                    Defines the offset applied to the M2 bending mode 20.
+                    Units in um.
+                  default: 0.0
+              ignore:
+                  description: >-
+                      CSCs from the group to ignore in status check. Name must
+                      match those in self.group.components, e.g.; hexapod_1.
+                  type: array
+                  items:
+                      type: string
+            additionalProperties: false
+        """
+        return yaml.safe_load(schema_yaml)
+
+    async def configure(self, config) -> None:
+        """Configure script.
+
+        Parameters
+        ----------
+        config : `types.SimpleNamespace`
+            Script configuration, as defined by `schema`.
+        """
+
+        # Configure tcs and camera
+        await self.configure_tcs()
+
+        if hasattr(config, "dofs"):
+            self.dofs = config.dofs
+        else:
+            # Loop through properties and assign their values to the vector
+            for key, value in vars(config).items():
+                self.dofs[getattr(DOFName, key)] = value
+
+        for comp in getattr(config, "ignore", []):
+            if comp not in self.mtcs.components_attr:
+                self.log.warning(
+                    f"Component {comp} not in CSC Group. "
+                    f"Must be one of {self.mtcs.components_attr}. Ignoring."
+                )
+            else:
+                self.log.debug(f"Ignoring component {comp}.")
+                setattr(self.mtcs.check, comp, False)
+
+    def set_metadata(self, metadata) -> None:
+        """Set script metadata.
+
+        Parameters
+        ----------
+        metadata : `lsst.ts.salobj.base.ScriptMetadata`
+            Script metadata.
+        """
+        metadata.duration = 10
+
+    async def assert_feasibility(self) -> None:
+        """Verify that the telescope is in a feasible state to
+        execute the script.
+        """
+
+        await self.mtcs.assert_all_enabled()
+
+    async def run(self) -> None:
+        """Run script."""
+        # Assert feasibility
+        await self.assert_feasibility()
+
+        await self.checkpoint("Setting DOF...")
+        current_dof = await self.mtcs.rem.mtaos.evt_degreeOfFreedom.aget(timeout=STD_TIMEOUT)
+        dof_data = self.mtcs.rem.mtaos.cmd_offsetDOF.DataType()
+        for i, dof_absolute in enumerate(self.dofs):
+            dof_data.value[i] = dof_absolute - current_dof.aggregatedDoF[i]
+        await self.mtcs.rem.mtaos.cmd_offsetDOF.start(data=offset_dof_data)
diff --git a/tests/test_maintel_set_dof.py b/tests/test_maintel_set_dof.py
new file mode 100644
index 000000000..bac695c37
--- /dev/null
+++ b/tests/test_maintel_set_dof.py
@@ -0,0 +1,115 @@
+# This file is part of ts_standardscripts
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+import random
+import types
+import unittest
+
+import numpy as np
+from lsst.ts import standardscripts
+from lsst.ts.observatory.control.maintel.mtcs import MTCS, MTCSUsages
+from lsst.ts.observatory.control.utils.enums import DOFName
+from lsst.ts.standardscripts.maintel import SetDOF
+
+random.seed(47)  # for set_random_lsst_dds_partition_prefix
+
+
+class TestSetDOF(
+    standardscripts.BaseScriptTestCase, unittest.IsolatedAsyncioTestCase
+):
+    async def basic_make_script(self, index):
+        self.script = SetDOF(index=index)
+
+        # Mock the MTCS
+        self.script.mtcs = MTCS(
+            domain=self.script.domain,
+            intended_usage=MTCSUsages.DryTest,
+            log=self.script.log,
+        )
+        self.script.mtcs.rem.mtaos = unittest.mock.AsyncMock()
+        self.script.mtcs.rem.mtaos.cmd_offsetDOF.attach_mock(
+            unittest.mock.Mock(
+                return_value=types.SimpleNamespace(value=np.zeros(len(DOFName)))
+            ),
+            "DataType",
+        )
+        self.script.mtcs.rem.mtaos.configure_mock(
+            **{
+                "evt_degreeOfFreedom.aget": self.get_current_dof,
+            }
+        )
+
+        self.script.mtcs.assert_all_enabled = unittest.mock.AsyncMock()
+
+        return (self.script,)
+
+    def get_current_dof():
+        return np.zeros(len(DOFName))
+
+    async def test_configure(self) -> None:
+        # Try configure with minimum set of parameters declared
+        async with self.make_script():
+            config_dofs = {"M2_dz": 0.2, "Cam_dy": 0.3, "M1M3_B1": 0.5, "M2_B14": 0.7}
+
+            await self.configure_script(**config_dofs)
+
+            dofs = np.zeros(len(DOFName))
+            for key, value in config_dofs.items():
+                dofs[getattr(DOFName, key)] = value
+
+            assert all(self.script.dofs == dofs)
+
+    async def test_configure_with_dofs_vector(self) -> None:
+        async with self.make_script():
+            dofs = [0] * len(DOFName)
+            config_dofs = {
+                "M2_dz": 0.2,
+                "Cam_dy": 0.3,
+                "M1M3_B1": 0.5,
+                "M2_B14": 0.7,
+                "dofs": dofs,
+            }
+
+            await self.configure_script(**config_dofs)
+
+            assert self.script.dofs == dofs
+
+    async def test_run(self) -> None:
+        # Start the test itself
+        async with self.make_script():
+            config_dofs = {"M2_dz": 0.2, "Cam_dy": 0.3, "M1M3_B1": 0.5, "M2_B14": 0.7}
+
+            await self.configure_script(**config_dofs)
+
+            # Run the script
+            await self.run_script()
+
+            self.script.mtcs.rem.mtaos.cmd_offsetDOF.DataType.assert_called()
+            self.script.mtcs.rem.mtaos.cmd_offsetDOF.start.assert_awaited_once()
+
+    async def test_executable(self) -> None:
+        scripts_dir = standardscripts.get_scripts_dir()
+        script_path = scripts_dir / "maintel" / "apply_dof.py"
+        await self.check_executable(script_path)
+
+
+if __name__ == "__main__":
+    unittest.main()