[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f9eB8FB9YYOI3za1rsSn7IcynXae2s99BIatAd9CPncc":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":33,"aiModel":30,"aiConfidence":30,"updatedAt":49,"createdAt":49,"_status":48},232,"What is exchangelib and how does it simplify Exchange Web Service development compared to lower-level SOAP XML methods?","Exchangelib is a Python library that abstracts the lower-level SOAP XML communication with Exchange servers. As covered in this [guide](\u002Fnews\u002Fexchange-web-service-ews-development-guide-5-exchangelib), it allows developers to access Exchange resources such as emails and attachments using simple Python objects, eliminating the need to manually construct SOAP messages. This is especially useful for automating tasks like email downloading or attachment extraction, whereas earlier articles in the [series](\u002Fnews\u002Fexchange-web-service-ews-development-guide) focused on raw XML for understanding protocol internals.","\u003Cp>Exchangelib is a Python library that abstracts the lower-level SOAP XML communication with Exchange servers. As covered in this [guide](\u002Fnews\u002Fexchange-web-service-ews-development-guide-5-exchangelib), it allows developers to access Exchange resources such as emails and attachments using simple Python objects, eliminating the need to manually construct SOAP messages. This is especially useful for automating tasks like email downloading or attachment extraction, whereas earlier articles in the [series](\u002Fnews\u002Fexchange-web-service-ews-development-guide) focused on raw XML for understanding protocol internals.\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fexchange-web-service-ews-development-guide-5-exchangelib\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","what-is-exchangelib-and-how-does-it-simplify-exchange-web-service-development-co-1777484493221","exchangelib, EWS, SOAP XML, Python library, email automation",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":27,"cover":30,"author":31,"views":19,"readingTime":32,"status":33,"publishedAt":34,"seo":35,"tags":39,"qaPairs":40,"meta":45,"updatedAt":46,"createdAt":47,"_status":48},61,"Exchange Web Service (EWS) Development Guide 5 – exchangelib","exchange-web-service-ews-development-guide-5-exchangelib","Learn to use exchangelib for EWS development, automate email downloads, and extract attachments with Python. Includes code examples and tips.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Previous articles introduced accessing Exchange resources using hash via SOAP XML messages. While this lower-level communication protocol makes implementation more cumbersome, it aids in understanding communication protocol principles and vulnerability exploitation.\u003C\u002Fp>\u003Cp>If the goal is simply to develop a more efficient program for resource access, the Python library exchangelib can be utilized.\u003C\u002Fp>\u003Cp>This article will cover the usage of exchangelib, provide open-source code, and demonstrate automated email downloading and attachment extraction.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Usage of exchangelib\u003C\u002Fli>\u003Cli>Development details\u003C\u002Fli>\u003Cli>Open-source code\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Usage of exchangelib\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Reference materials:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fecederstrand\u002Fexchangelib\u003C\u002Fp>\u003Cp>https:\u002F\u002Fecederstrand.github.io\u002Fexchangelib\u002F\u003C\u002Fp>\u003Ch3>1. Simple login test\u003C\u002Fh3>\u003Cp>Code as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>from exchangelib import Credentials, Account, Configuration, DELEGATE\u003Cbr>credentials = Credentials(username='MYWINDOMAIN\\\\myuser', password='topsecret')\u003Cbr>config = Configuration(server='outlook.office365.com', credentials=credentials)\u003Cbr>account = Account(primary_smtp_address='john@example.com', config=config,\u003Cbr>                  autodiscover=False, access_type=DELEGATE)\u003Cbr>for item in account.inbox.all().order_by('-datetime_received')[:100]:\u003Cbr>    print(item.subject, item.sender, item.datetime_received)\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>If the Exchange server certificate is untrusted, add the following code to ignore certificate verification:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter\u003Cbr>BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>To suppress the InsecureRequestWarning output, add the following code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>import urllib3\u003Cbr>urllib3.disable_warnings()\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Complete code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>from exchangelib import Credentials, Account, Configuration, DELEGATE\u003Cbr>from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter\u003Cbr>BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter\u003Cbr>import urllib3\u003Cbr>urllib3.disable_warnings()\u003Cbr>credentials = Credentials(username='MYWINDOMAIN\\\\myuser', password='topsecret')\u003Cbr>config = Configuration(server='outlook.office365.com', credentials=credentials)\u003Cbr>account = Account(primary_smtp_address='john@example.com', config=config,\u003Cbr>                  autodiscover=False, access_type=DELEGATE)\u003Cbr>for item in account.inbox.all().order_by('-datetime_received')[:100]:\u003Cbr>    print(item.subject, item.sender, item.datetime_received)\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>2. Use plaintext or hash login\u003C\u002Fh3>\u003Cp>Using plaintext login:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>credentials = Credentials('MYWINDOMAIN\\\\myuser', 'topsecret')\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Using hash login:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>credentials = Credentials('MYWINDOMAIN\\\\myuser', '00000000000000000000000000000000:7C451851EA87B63EC7692126416D01EB')\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>3. Count the number of emails\u003C\u002Fh3>\u003Cp>Example code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>n = a.inbox.all().count()\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>4. Search within a specified time range\u003C\u002Fh3>\u003Cp>Example code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>for item in account.inbox.filter(datetime_received__gt=EWSDateTime(2021, 1, 20, tzinfo=account.default_timezone)):\u003Cbr>    print(item.subject, item.sender, item.datetime_received)\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>5. Specify the download quantity:\u003C\u002Fh3>\u003Cp>Specify the first 10:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>first_ten = a.inbox.all()[:10]\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Specify the last 10:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>last_ten = a.inbox.all()[:-10]\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Specified interval:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>next_ten = a.inbox.all()[10:20]\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>6. Folder enumeration\u003C\u002Fh3>\u003Cp>Can traverse all folders under the mailbox user, example code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>print(account.root.tree())\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>7. Compiling Python scripts into exe\u003C\u002Fh3>\u003Cp>If compiling a Python script developed using exchangelib into exe format, using the command pyinstaller -F test.py will result in an error, indicating: No time zone found with key UTC\u003C\u002Fp>\u003Cp>Solution:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>pyinstaller --collect-all tzdata --onefile test.py\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch2>0x03 Development details\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Communication protocol\u003C\u002Fh3>\u003Cp>exchangelib also utilizes SOAP XML messages to access Exchange resources using hash\u003C\u002Fp>\u003Ch3>2. Mail saving\u003C\u002Fh3>\u003Cp>In exchangelib, XML-formatted email content is automatically parsed, allowing direct extraction of corresponding information when saving emails.\u003C\u002Fp>\u003Cp>Note that the string \\r\\n in the returned results can be replaced with line breaks to improve data readability.\u003C\u002Fp>\u003Cp>Example code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>filtered_items = email.inbox.all()\u003Cbr>for item in items:\u003Cbr>    with open(item.id, \"w\") as fw:\u003Cbr>        fw.write(str(item).replace('\\\\r\\\\n','\\r\\n'))\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>3. Conditional Matching\u003C\u002Fh3>\u003Cp>exchangelib supports Advanced Query Syntax (AQS)\u003C\u002Fp>\u003Cp>AQS reference:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fexchange\u002Fclient-developer\u002Fweb-service-reference\u002Fquerystring-querystringtype\u003C\u002Fp>\u003Cp>Using AQS enables date searches, with search format examples:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>sent:&gt;=2021\u002F1\u002F1 AND sent:&lt;=2021\u002F12\u002F30\u003Cbr>received:&gt;=2021\u002F1\u002F1 AND received:&lt;=2021\u002F12\u002F30\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For keyword searches, AQS cannot be used directly; you may choose to receive all emails and then perform string matching.\u003C\u002Fp>\u003Ch2>0x04 Open Source Code\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>The complete code has been uploaded to GitHub at the following address:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>Supports login with plaintext and NTLM Hash, the code supports the following features:\u003C\u002Fp>\u003Cul>\u003Cli>Supports custom Exchange servers and Office365 (outlook.office365.com)\u003C\u002Fli>\u003Cli>download, download emails and extract attachments, with options to specify mailbox folders and download quantities\u003C\u002Fli>\u003Cli>search, email search and download, supports syntax for keywords, time, length, etc.\u003C\u002Fli>\u003Cli>listfolder, enumerate all user folders\u003C\u002Fli>\u003C\u002Ful>\u003Cp>When downloading emails, the email username is used as the parent folder, and different operations create different subfolders. When using the search function to create subfolders, special characters (such as &gt;) that cannot be used as folder names are removed to avoid issues.\u003C\u002Fp>\u003Ch2>0x05 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article introduces the usage of exchangelib, the open-source code ewsManage_exchangelib_Downloader.py, which enables access to Exchange resources using hash authentication.\u003C\u002Fp>\u003Cp>If you want to quickly develop a program for accessing EWS resources, exchangelib is recommended.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr",null,"Onedaysec",3,"published","2026-02-02T08:07:20.755Z",{"title":36,"description":14,"keywords":37,"ogImage":30,"canonicalUrl":30,"noIndex":38},"Exchange Web Service EWS Development Guide with exchangelib","exchangelib, EWS, Exchange Web Service, Python, email automation, SOAP XML, hash login",false,[],{"docs":41,"hasNextPage":38},[42,43,44,4],235,234,233,{"title":30,"description":30,"image":30},"2026-07-24T02:07:27.587Z","2026-07-23T16:01:13.289Z","draft","2026-07-23T16:04:43.581Z"]