diff --git a/scripts/smb2-os-discovery.nse b/scripts/smb2-os-discovery.nse
new file mode 100644
index 000000000..7bd4534f7
--- /dev/null
+++ b/scripts/smb2-os-discovery.nse
@@ -0,0 +1,352 @@
+local smb = require "smb"
+local smb2 = require "smb2"
+local stdnse = require "stdnse"
+local table = require "table"
+local nmap = require "nmap"
+
+description = [[
+Attempts to determine the operating system, computer name, domain name, and current
+time over the SMB2 protocol (ports 445 or 139).
+]]
+
+---
+-- @usage nmap --script smb-os-discovery.nse -p445 127.0.0.1
+--
+-- @output
+-- | Host script results:
+-- | smb2-os-discovery:
+-- | OS: Windows 10 2004 (OS build 19041)
+-- | OS CPE: cpe:/o:microsoft:windows_10
+-- | NetBIOS Domain Name: Test
+-- | NetBIOS Computer Name: Test
+-- | Dns Domain Name:
+-- | Dns Computer Name: localhost
+-- |_ Timestamp: 2024-02-15 13:42:29
+
+-- @xmloutput
+-- Windows 10 2004 (OS build 19041)
+-- cpe:/o:microsoft:windows_10
+-- Test
+-- Test
+--
+-- localhost
+-- 2024-02-15 13:42:29
+---
+
+author = "galycannon"
+license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
+categories = {"safe", "discovery"}
+
+hostrule = function(host)
+ return smb.get_port(host) ~= nil
+end
+
+action = function(host,port)
+ local status, smbstate, overrides
+ overrides = {}
+
+ status, smbstate = smb.start(host)
+ if(status == false) then
+ return stdnse.format_output(false, "Connection error.")
+ end
+
+ local max_dialect
+ status, max_dialect = smb2.negotiate_v2(smbstate)
+ if not status then
+ return stdnse.format_output(false, "SMB 2+ not supported")
+ end
+
+ response, stdnse_output = session_setup(smbstate)
+ smb.stop(smbstate)
+
+ return response, stdnse_output
+end
+
+function session_setup(smb)
+ local overrides = {}
+ overrides['CreditCharge'] = 1
+ overrides['CreditR'] = 33
+ overrides['MessageId'] = 1
+ overrides['Signature'] = 0
+ local header = smb2.smb2_encode_header_sync(smb, 0x0001, overrides)
+
+ local StructureSize = 0x19
+ local Flags = 0
+ local SecurityMode = 1
+ local Capabilities = 0
+ local Channel = 0
+ local Blob_Offset = 0x58
+ local Blob_Length = 74
+ local Pre_Session_Id = 0
+
+ local data = string.pack(" 0 then
+ return "cpe:/" .. table.concat(parts, ":")
+ end
+end
+
+-- https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/83f5e789-660d-4781-8491-5f8c6641f75e
+function parse_data(data)
+ local results = {}
+ local i = 1
+ while i <= #data do
+ local target_type, new_pos = string.unpack(" 0 then
+ content, new_pos = string.unpack("c" .. target_len, data, i)
+ i = new_pos
+ else
+ content = ""
+ end
+
+ local function hex2ascii(hexStr)
+ local utf16leStr = ""
+ for i = 1, #hexStr, 2 do
+ local hexCode = string.unpack("